You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

分组查询:避免返回列值变更前后的重复列值行

解决思路:过滤掉连续重复的分组编辑记录

嘿,这个需求我之前帮人处理过类似的,先跟你确认下我的理解:你想要的是把同一帖子下同一作者连续编辑的重复行过滤掉——也就是当post_id和author_id的组合连续重复时,只保留其中一条,避免返回这些连续重复的行;而如果作者切换了(哪怕之后又切回原作者),这些新的编辑记录要保留。如果我理解错了,你随时补充说明哈!

方法1:用LAG()窗口函数快速过滤连续重复行

这个方法最直接,用窗口函数LAG()获取当前行的前一行分组信息,对比如果和当前行一致就过滤掉,只保留分组变化的节点和第一行。

拿MySQL举例子,SQL语句是这样的:

SELECT post_id, author_id, edit_message, date
FROM (
    SELECT 
        post_id, author_id, edit_message, date,
        -- 获取前一行的分组标识(把post_id和author_id拼起来)
        LAG(CONCAT(post_id, '-', author_id)) OVER (ORDER BY date) AS prev_group
    FROM post_edits
) AS sub_query
-- 保留第一行,或者和前一行分组不同的行
WHERE prev_group IS NULL 
   OR CONCAT(post_id, '-', author_id) != prev_group;

要是你用的是PostgreSQL这类支持行比较的数据库,还能写得更优雅:

SELECT post_id, author_id, edit_message, date
FROM (
    SELECT 
        post_id, author_id, edit_message, date,
        LAG((post_id, author_id)) OVER (ORDER BY date) AS prev_group
    FROM post_edits
) AS sub_query
WHERE prev_group IS NULL OR (post_id, author_id) != prev_group;

方法2:保留每个连续分组的最新编辑记录

如果你不想只留分组的第一条,而是想保留每个连续编辑阶段的最新那条消息,就可以用ROW_NUMBER()窗口函数配合分组ID来实现:

SELECT post_id, author_id, edit_message, date
FROM (
    SELECT 
        post_id, author_id, edit_message, date,
        ROW_NUMBER() OVER (
            PARTITION BY group_id 
            ORDER BY date DESC
        ) AS row_num
    FROM (
        SELECT 
            post_id, author_id, edit_message, date,
            -- 生成连续分组的ID:每次分组变化就加1
            SUM(CASE WHEN prev_group = CONCAT(post_id, '-', author_id) THEN 0 ELSE 1 END) OVER (ORDER BY date) AS group_id
        FROM (
            SELECT 
                post_id, author_id, edit_message, date,
                LAG(CONCAT(post_id, '-', author_id)) OVER (ORDER BY date) AS prev_group
            FROM post_edits
        ) AS step1
    ) AS step2
) AS step3
WHERE row_num = 1
ORDER BY date;

简单说下逻辑:

  1. 最内层先拿到每行的前一行分组;
  2. 中间层给每个连续的相同分组分配一个唯一ID,分组一变ID就加1;
  3. 最外层按分组ID拆分,每个分组里按时间倒序排,取第一行就是这个连续编辑阶段的最新记录。

举个实际结果例子

用你给的样本数据,按时间排序后:

  1. post1, author1, "first author's first edit to post 1", 2018-03-19 12:00:00
  2. post1, author1, "first author's second edit to post 1", 2018-03-19 12:05:00
  3. post2, author1, "first author's first edit to post 2", 2018-03-19 12:10:00
  4. post1, author1, "first author's third edit to post 1", 2018-03-19 12:15:00
  5. post1, author2, "second author's first edit to post 1", 2018-03-19 12:20:00
  6. post1, author1, "first author's fourth edit to post 1", ...

用方法1得到的结果是:行1、行3、行4、行5、行6——把连续重复的行2过滤掉了。

用方法2得到的结果是:行2、行3、行4、行5、行6——每个连续分组只留最新的那条。

小提醒

  • 要确保你的数据库支持窗口函数哈,比如MySQL 8.0+、PostgreSQL、SQL Server这些都没问题;
  • 排序全靠date列,要是有相同时间的编辑记录,最好加个自增ID当额外排序字段,保证顺序不会乱。

内容的提问来源于stack exchange,提问作者Sean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:32:04