如何按weekday分组获取employee_id=1优先的唯一日历记录?
解决每个Weekday优先取指定Employee记录的问题
我来帮你搞定这个问题~咱们先说说你原来的查询为啥没得到预期结果:你用GROUP BY weekday的时候,如果MySQL没开启ONLY_FULL_GROUP_BY模式,它会随机返回每个分组里的一条记录,没法保证优先选中employee_id=1的那条,这就是结果不符合你预期的原因。
下面给你两种可行的解法,适配不同的MySQL版本:
方法1:用窗口函数(MySQL 8.0及以上版本)
窗口函数可以很方便地给每个weekday分组的记录设置优先级,然后选出优先级最高的那条:
WITH ranked_calendar AS ( SELECT *, -- 给employee_id=1的记录标记优先级1,其他(这里是NULL)标记2 ROW_NUMBER() OVER ( PARTITION BY weekday ORDER BY CASE WHEN employee_id = 1 THEN 1 ELSE 2 END ) AS rn FROM `calendar` ) SELECT id, weekday, employee_id, status FROM ranked_calendar WHERE rn = 1;
这个查询会先给每个weekday的记录排序,把employee_id=1的排在最前面,然后只取每个分组里的第一条记录,正好符合你要的“优先取有值记录,无值则取NULL”的需求。
方法2:用UNION ALL(适配所有MySQL版本)
如果你的MySQL版本不支持窗口函数,可以用UNION ALL组合两个查询:先取出所有employee_id=1的记录,再补上那些没有employee_id=1的weekday对应的NULL记录:
-- 第一步:取出所有employee_id=1的记录 SELECT * FROM `calendar` WHERE `employee_id` = 1 UNION ALL -- 第二步:取出那些没有employee_id=1的weekday的NULL记录 SELECT * FROM `calendar` WHERE `employee_id` IS NULL AND `weekday` NOT IN (SELECT `weekday` FROM `calendar` WHERE `employee_id` = 1);
这种方法逻辑直白,先拿优先级高的记录,再补充缺失的分组的NULL记录,也能得到你期望的结果。
这两种方法都能实现你要的效果,你可以根据自己的MySQL版本选择使用~
内容的提问来源于stack exchange,提问作者Davit Zeynalyan
相关产品推荐
相关产品推荐

