SQL按日期与job_name分组,按优先级规则返回status的实现求助
问题需求
现有数据表包含date_time、job_name、status三列,任务每日可运行一次或多次,status取值为success、failed、disabled。需按**日期(仅提取date_time的日期部分)**与job_name分组,每组status遵循以下优先级返回:
- 当日该任务存在
failed记录时,返回failed - 无
failed但存在disabled记录时,返回disabled - 所有记录均为
success时,返回success
尝试过GROUP BY分组,但无法实现上述状态判断逻辑,寻求解决方案。
示例数据
| date_time | job_name | status |
|---|---|---|
| 01/01/2020 07:30:30 | job_1 | success |
| 01/01/2020 15:30:30 | job_1 | disabled |
| 01/01/2020 18:30:30 | job_1 | failed |
| 01/01/2020 08:30:30 | job_2 | success |
| 01/01/2020 18:30:30 | job_2 | disabled |
| 01/02/2020 15:30:30 | job_1 | success |
| 01/02/2020 08:30:30 | job_2 | success |
| 01/02/2020 18:30:30 | job_2 | success |
预期结果
| date_time | job_name | status |
|---|---|---|
| 01/01/2020 | job_1 | failed |
| 01/01/2020 | job_2 | disabled |
| 01/02/2020 | job_1 | success |
| 01/02/2020 | job_2 | success |
解决方案
方法一:状态优先级聚合法
给不同状态分配优先级数值(failed=3,disabled=2,success=1),通过MAX()函数取每组最高优先级对应的状态,适配主流数据库:
MySQL / PostgreSQL
SELECT DATE(date_time) AS date_time, job_name, CASE MAX( CASE status WHEN 'failed' THEN 3 WHEN 'disabled' THEN 2 ELSE 1 END ) WHEN 3 THEN 'failed' WHEN 2 THEN 'disabled' ELSE 'success' END AS status FROM your_table_name GROUP BY DATE(date_time), job_name;
SQL Server
SELECT CONVERT(date, date_time) AS date_time, job_name, CASE MAX( CASE status WHEN 'failed' THEN 3 WHEN 'disabled' THEN 2 ELSE 1 END ) WHEN 3 THEN 'failed' WHEN 2 THEN 'disabled' ELSE 'success' END AS status FROM your_table_name GROUP BY CONVERT(date, date_time), job_name;
方法二:存在性判断法
通过子查询依次检查每组是否包含高优先级状态,逻辑更直观:
-- MySQL示例,其他数据库替换日期处理函数即可 SELECT DATE(date_time) AS date_time, job_name, CASE WHEN EXISTS ( SELECT 1 FROM your_table_name t2 WHERE DATE(t2.date_time) = DATE(t1.date_time) AND t2.job_name = t1.job_name AND t2.status = 'failed' ) THEN 'failed' WHEN EXISTS ( SELECT 1 FROM your_table_name t2 WHERE DATE(t2.date_time) = DATE(t1.date_time) AND t2.job_name = t1.job_name AND t2.status = 'disabled' ) THEN 'disabled' ELSE 'success' END AS status FROM your_table_name t1 GROUP BY DATE(date_time), job_name;
内容的提问来源于stack exchange,提问作者basrood
相关产品推荐
相关产品推荐

