如何编写SQL WHERE子句筛选同NotificationID但不同DateTime的记录
如何筛选同一NotificationID下DateTime存在差异的记录?
这是个很常见的分组筛选需求,我来给你梳理几种可行的SQL写法,你可以根据实际想要的结果来选择:
场景1:筛选所有与同组内任意记录DateTime不同的记录
如果你的需求是:只要某条记录和同NotificationID下的任意一条其他记录DateTime不同,就保留这条记录(也就是同组内只要存在不同DateTime,所有记录都返回),可以用EXISTS子查询实现,这是最直观且性能不错的写法(建议给NotificationID和DateTime建索引优化查询速度):
SELECT * FROM your_table t_main WHERE EXISTS ( SELECT 1 FROM your_table t_compare WHERE t_compare.NotificationID = t_main.NotificationID AND t_compare.DateTime != t_main.DateTime )
解释:对于每条主表记录,我们检查是否存在同NotificationID但DateTime不同的记录,如果存在,就保留这条主记录。在你的示例数据中,这会返回所有4条记录——因为ID=2/3/4都和ID=1的DateTime不同,而ID=1也和它们不同。
场景2:只筛选同组内DateTime出现次数最少的记录
如果你的需求是仅保留像示例中ID=1这类,和组内大多数记录DateTime不同的记录(也就是DateTime出现次数最少的那些记录),可以用窗口函数来实现:
WITH record_counts AS ( SELECT ID, NotificationID, DateTime, -- 计算当前DateTime在同NotificationID组内的出现次数 COUNT(*) OVER (PARTITION BY NotificationID, DateTime) AS dt_occurrences, -- 找出同组内DateTime出现次数的最小值 MIN(COUNT(*)) OVER (PARTITION BY NotificationID) AS min_occurrences FROM your_table ) SELECT ID, NotificationID, DateTime FROM record_counts WHERE dt_occurrences = min_occurrences
解释:CTE(公共表表达式)部分给每条记录加上两个计算字段:dt_occurrences是该DateTime在同NotificationID组里出现的次数,min_occurrences是该组内所有DateTime出现次数的最小值。最后筛选出出现次数等于最小值的记录,在你的示例中只会返回ID=1这条记录。
如果你的数据库不支持CTE(比如MySQL 5.7及更早版本),可以把CTE改成子查询形式:
SELECT ID, NotificationID, DateTime FROM ( SELECT ID, NotificationID, DateTime, COUNT(*) OVER (PARTITION BY NotificationID, DateTime) AS dt_occurrences, MIN(COUNT(*)) OVER (PARTITION BY NotificationID) AS min_occurrences FROM your_table ) AS subquery WHERE dt_occurrences = min_occurrences
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

