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

SQL:将重复列值替换为空值的实现方案

实现重复列值置空的报表式查询

问题场景

你有这样一张数据表:

CompanyDatePaperCondition
Company119-12-2007PaperARelease Second Term
Company119-12-2007PaperAAdd Third Term
Company119-12-2007PaperAAppend First Term

想要把重复的Company、Date、Paper列值替换为空,得到类似报表合并单元格的效果:

CompanyDatePaperCondition
Company119-12-2007PaperARelease Second Term
Add Third Term
Append First Term

之前用DISTINCT没达到效果?太正常了——DISTINCT是用来去重整行数据的,根本不是干这个活的~下面给你几种不同数据库环境下的实现方法:


方法1:用窗口函数(推荐,适用于MySQL 8+、SQL Server、PostgreSQL等)

现在大部分主流数据库都支持窗口函数,用ROW_NUMBER()给每组相同的Company、Date、Paper编号,然后只保留每组第一行的原值,其他行置为空即可:

SELECT
    -- 只有组内第一行显示原值,其余为空
    CASE WHEN rn = 1 THEN Company ELSE '' END AS Company,
    CASE WHEN rn = 1 THEN Date ELSE '' END AS Date,
    CASE WHEN rn = 1 THEN Paper ELSE '' END AS Paper,
    Condition
FROM (
    -- 子查询给每组数据编号
    SELECT
        *,
        ROW_NUMBER() OVER (
            PARTITION BY Company, Date, Paper  -- 按这三列分组
            ORDER BY Condition                 -- 组内排序,确定哪行是第一行
        ) AS rn
    FROM your_table_name  -- 替换成你的表名
) t
-- 保持排序一致,避免结果混乱
ORDER BY Company, Date, Paper, rn;

如果你想指定组内第一行是特定的记录,调整ORDER BY后面的字段就行,比如按Condition的业务逻辑排序。


方法2:MySQL 5.x及以下版本(无窗口函数)

旧版MySQL没有窗口函数,我们可以用用户变量来记录上一行的值,实现相同效果:

SELECT
    CASE WHEN @prev_company = Company THEN '' ELSE @prev_company := Company END AS Company,
    CASE WHEN @prev_date = Date THEN '' ELSE @prev_date := Date END AS Date,
    CASE WHEN @prev_paper = Paper THEN '' ELSE @prev_paper := Paper END AS Paper,
    Condition
FROM your_table_name,
     -- 初始化变量为空字符串
     (SELECT @prev_company := '', @prev_date := '', @prev_paper := '') vars
-- 必须按分组列排序,不然变量记录会出错
ORDER BY Company, Date, Paper, Condition;

⚠️ 注意:这种写法一定要加上ORDER BY,保证相同分组的行连续出现,否则变量的判断会混乱。


小提醒

这种处理只是在查询结果中做展示用,千万不要直接修改原表把重复值改成空值!原表保留完整数据才是正确的做法,空值会丢失原始信息,后续统计或查询都会出问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:23:18