MySQL查询需求:按HRD部门获取覆盖后的目标数据
解决方案:获取HRD部门的目标数据集
没问题,我来帮你搞定这个MySQL查询需求!咱们先理清楚核心逻辑:每个std_type优先用HRD部门的专属记录,如果没有该类型的HRD记录,就 fallback 到ALL部门的默认值。下面是两种可行的方案,优先推荐更简洁高效的窗口函数写法:
方案1:使用窗口函数(推荐)
这种方法通过给每个std_type分组内的记录排序,优先保留HRD部门的记录,逻辑清晰且性能较好:
SELECT DISTINCT std_id, std_type, std_dept, target FROM ( SELECT *, -- 给每个类型的记录排序:HRD排第1,ALL排第2 ROW_NUMBER() OVER ( PARTITION BY std_type ORDER BY CASE WHEN std_dept = 'HRD' THEN 1 ELSE 2 END ) AS rn FROM your_table_name -- 只筛选和HRD相关的记录:要么是HRD专属,要么是全局默认 WHERE std_dept IN ('HRD', 'ALL') ) AS ranked_records -- 取每个类型的第一条记录(优先HRD,没有则取ALL) WHERE rn = 1;
逻辑解释:
- 内层查询先过滤出
std_dept为HRD或ALL的记录,排除其他无关部门的数据; - 用
ROW_NUMBER()按std_type分组,对每组内的记录排序:HRD部门的记录标记为第1位,全局默认(ALL)的标记为第2位; - 外层查询只保留每组的第一条记录(
rn=1),这样就自动实现了“专属记录覆盖全局默认”的规则。
方案2:使用JOIN和UNION(兼容旧版MySQL)
如果你的MySQL版本不支持窗口函数(低于8.0),可以用这种JOIN+UNION的方式实现:
SELECT DISTINCT -- 优先取HRD的记录,没有则取ALL的 COALESCE(hrd.std_id, all_std.std_id) AS std_id, COALESCE(hrd.std_type, all_std.std_type) AS std_type, COALESCE(hrd.std_dept, all_std.std_dept) AS std_dept, COALESCE(hrd.target, all_std.target) AS target FROM ( -- 获取HRD部门的所有记录 SELECT std_type, std_id, std_dept, target FROM your_table_name WHERE std_dept = 'HRD' ) hrd RIGHT JOIN ( -- 获取全局默认的所有记录 SELECT std_type, std_id, std_dept, target FROM your_table_name WHERE std_dept = 'ALL' ) all_std ON hrd.std_type = all_std.std_type -- 补充那些只有HRD记录、没有全局默认的情况(虽然你的示例里没有,但逻辑上要覆盖) UNION ALL SELECT std_id, std_type, std_dept, target FROM your_table_name WHERE std_dept = 'HRD' AND std_type NOT IN (SELECT std_type FROM your_table_name WHERE std_dept = 'ALL');
逻辑解释:
- 通过
RIGHT JOIN把全局默认记录和HRD专属记录关联,用COALESCE优先取HRD的字段值; - 用
UNION ALL补充那些只有HRD记录、没有全局默认的特殊情况,确保数据完整性。
两种方案都能得到你期望的结果,替换your_table_name为实际的数据表名即可。
内容的提问来源于stack exchange,提问作者fajar setiawan
相关产品推荐
相关产品推荐

