SQL查询需求:按日期排除Job列重复数据
去除同一天内重复Job行的SQL查询改造
要实现排除DispDate同一天内重复Job行的需求,核心是对(Job, DispDate)组合做去重,以下是两种可行的改造方案:
方案一:使用窗口函数(推荐)
窗口函数能精准控制保留每组的指定行,适配大多数现代数据库(如SQL Server、MySQL 8+、PostgreSQL等):
SELECT job, dispdate, disptime, moddate, modtime, description, who FROM ( SELECT t.job, t.dispdate, t.disptime, th.moddate, th.modtime, th.description, th.who, -- 按日期和Job分组,给组内每行编号 ROW_NUMBER() OVER (PARTITION BY t.dispdate, t.job ORDER BY th.moddate, th.modtime) AS row_num FROM Trip_History AS th LEFT JOIN Trips t ON th.job = t.job AND th.tdate = t.tdate WHERE CONVERT(TIME(0), th.modtime) >= CONVERT(TIME(0), t.disptime) AND th.moddate >= t.dispdate AND th.description LIKE '%Changed Pick-Up Facility%' AND th.description NOT LIKE '%From Giles County%' AND t.dispdate > '2023-01-01' ) AS filtered_data -- 只保留每组的第一行 WHERE row_num = 1;
逻辑说明:
PARTITION BY t.dispdate, t.job:将数据按日期和Job分组,确保同一天同一Job的所有行归为一组。ORDER BY th.moddate, th.modtime:指定组内行的排序规则,这里取最早的修改记录,你可根据业务需求换成t.disptime或其他字段。- 外层筛选
row_num = 1,直接排除组内重复行,只保留每组第一条记录。
方案二:使用GROUP BY(兼容低版本数据库)
如果你的数据库不支持窗口函数,可通过分组聚合实现:
SELECT t.job, t.dispdate, MIN(t.disptime) AS disptime, MIN(th.moddate) AS moddate, MIN(th.modtime) AS modtime, MAX(th.description) AS description, MAX(th.who) AS who FROM Trip_History AS th LEFT JOIN Trips t ON th.job = t.job AND th.tdate = t.tdate WHERE CONVERT(TIME(0), th.modtime) >= CONVERT(TIME(0), t.disptime) AND th.moddate >= t.dispdate AND th.description LIKE '%Changed Pick-Up Facility%' AND th.description NOT LIKE '%From Giles County%' AND t.dispdate > '2023-01-01' GROUP BY t.job, t.dispdate;
注意事项:
- 聚合函数(如
MIN、MAX)的选择要贴合业务逻辑:如果description和who在同一(Job, DispDate)组内值一致,用MIN或MAX都可以;如果存在差异,需明确要保留哪一个值。
内容的提问来源于stack exchange,提问作者Dustin Elgin
相关产品推荐
相关产品推荐

