SQL查询:过滤连续重复的电视节目记录,仅保留首条
解决连续重复节目过滤的SQL方案
嘿,作为SQL新手遇到这种需求很正常,其实核心就是要识别连续重复的节目条目,只保留每组连续重复的第一条。我来给你详细说下思路和具体实现:
核心思路
我们需要把每一行的节目标题和它的上一行标题做对比:
- 如果当前行的标题和上一行不一样,就保留这一行;
- 如果一样,说明是连续重复的节目,就过滤掉;
- 第一行没有上一行,直接保留。
这里最方便的工具是窗口函数LAG(),它可以帮我们获取到当前行的前一行数据,完美适配这个场景。
具体SQL实现
假设你的节目单表名叫tv_schedule,字段是Time(注意这个是SQL关键字,不同数据库可能需要用反引号/双引号包裹)和Title,可以用下面的查询语句:
SELECT `Time`, Title FROM ( SELECT `Time`, Title, -- 获取上一行的节目标题,按时间排序 LAG(Title) OVER (ORDER BY `Time`) AS prev_title FROM tv_schedule ) AS subquery -- 筛选:要么是第一行(prev_title为NULL),要么当前标题和上一行不同 WHERE prev_title IS NULL OR Title != prev_title ORDER BY `Time`;
代码解释
- 内层子查询用
LAG(Title) OVER (ORDER BY Time),按时间顺序为每一行生成上一行的节目标题prev_title; - 外层查询只保留两种情况:
prev_title IS NULL:这是时间最早的第一行,直接保留;Title != prev_title:当前节目和上一行不一样,说明是新的节目,保留。
用你给出的测试数据跑这个查询,就能得到你期望的结果啦!
兼容老版本数据库(比如MySQL < 8.0)
如果你的数据库不支持窗口函数(比如老版本MySQL),可以用变量来实现:
SELECT `Time`, Title FROM ( SELECT `Time`, Title, @prev_title AS prev_title, -- 更新变量为当前标题,用于下一行对比 @prev_title := Title FROM tv_schedule, (SELECT @prev_title := NULL) AS init_var ORDER BY `Time` ) AS subquery WHERE prev_title IS NULL OR Title != prev_title ORDER BY `Time`;
这个方法是用变量@prev_title来记录上一行的节目标题,逐行对比筛选。
内容的提问来源于stack exchange,提问作者SamTheSwede
相关产品推荐
相关产品推荐

