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

使用SQL(Hive/Impala语法)删除重复行

解决基于指定字段去重并保留特定行的问题

这问题我平时处理数据时碰到过好多次,SELECT DISTINCT确实搞不定这种只按部分列去重的场景——它会把所有列的组合都算进去,所以哪怕只有一列不同,都会被当成唯一行。针对你要保留2018-02-07重复条目中第二条的需求,最靠谱的方法是用窗口函数ROW_NUMBER(),下面给你具体实现:

方法一:使用CTE结合窗口函数(推荐)

假设你的原查询简化后是这样的:

SELECT event_dates, case_ids, other_column
FROM your_table
-- 这里是原查询的其他过滤/关联条件

我们可以把原查询包装成一个CTE,给每个(event_dates, case_ids)组合的行按你需要的顺序编号,最后筛选出编号为2的行:

WITH ranked_rows AS (
    SELECT 
        event_dates, 
        case_ids, 
        other_column,
        -- 按能区分"第二条"的列排序,比如主键id、创建时间等
        ROW_NUMBER() OVER (
            PARTITION BY event_dates, case_ids 
            ORDER BY id ASC -- 替换成你实际用来确定行顺序的列
        ) AS row_num
    FROM your_table
    -- 原查询的所有条件都放这里
)
SELECT event_dates, case_ids, other_column
FROM ranked_rows
WHERE row_num = 2;

关键逻辑解释:

  • PARTITION BY event_dates, case_ids:把所有event_dates和case_ids完全相同的行归为一组
  • ORDER BY id ASC:决定组内行的排序顺序,这里按id升序的话,组内的第二行就是row_num=2的那条;如果你要保留的是最新插入的行,可以改成ORDER BY create_time DESC,然后取row_num=1也能达到类似效果
  • ROW_NUMBER():给每组内的行从1开始依次编号,最后筛选编号为2的行就实现了只保留每组的第二条

方法二:兼容老版本SQL的子查询写法

如果你的数据库不支持CTE(比如MySQL 5.x及以前),可以把上面的逻辑改成子查询形式:

SELECT event_dates, case_ids, other_column
FROM (
    SELECT 
        event_dates, 
        case_ids, 
        other_column,
        ROW_NUMBER() OVER (
            PARTITION BY event_dates, case_ids 
            ORDER BY id ASC
        ) AS row_num
    FROM your_table
    -- 原查询的所有条件
) AS sub_query
WHERE row_num = 2;

注意事项:

一定要保证ORDER BY后面的列能稳定区分行,比如用主键、唯一时间戳这类不会重复的字段,不然每次执行查询可能得到不同的结果,没法稳定保留你想要的那条行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:09:56