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

SQL技术问询:特定条件下重复行的处理方案

处理重复行的SQL解决方案

看起来你是要处理表中同一用户的重复行问题——比如示例里的John,一行有牙齿区域的数据,另一行只有服务记录但牙齿字段全为空。下面给你两种常见场景的SQL解决方案,你可以根据实际需求选择:

原始数据表

IDNameRecievedServiceFirstZoneTeethSecondZoneTeethThirdZoneTeethFourthZoneTeeth
1JohnSomeService1134
2JohnSomeService...

场景1:合并重复行的非空数据

如果需要保留所有服务记录,同时把同一用户的牙齿数据填充到每一行中(避免空值),可以用CTE结合聚合函数来实现:

WITH user_teeth_summary AS (
    SELECT 
        Name,
        -- MAX会自动忽略空值,取每个用户对应的非空牙齿数据
        MAX(FirstZoneTeeth) AS FirstZoneTeeth,
        MAX(SecondZoneTeeth) AS SecondZoneTeeth,
        MAX(ThirdZoneTeeth) AS ThirdZoneTeeth,
        MAX(FourthZoneTeeth) AS FourthZoneTeeth
    FROM your_table_name
    GROUP BY Name
)
SELECT 
    t.ID,
    t.Name,
    t.RecievedService,
    uts.FirstZoneTeeth,
    uts.SecondZoneTeeth,
    uts.ThirdZoneTeeth,
    uts.FourthZoneTeeth
FROM your_table_name t
JOIN user_teeth_summary uts ON t.Name = uts.Name;

执行后,John的两行记录都会带上FirstZoneTeeth=13和ThirdZoneTeeth=4的非空数据。


场景2:删除无有效数据的重复行

如果只需要保留每个用户包含牙齿数据的那一行,删掉没有任何牙齿信息的重复行,可以用两种方式实现:

方式1:用子查询筛选保留行

-- 先确认要保留的行(建议先执行SELECT验证)
SELECT MAX(ID) AS keep_id
FROM your_table_name
WHERE FirstZoneTeeth IS NOT NULL 
    OR SecondZoneTeeth IS NOT NULL 
    OR ThirdZoneTeeth IS NOT NULL 
    OR FourthZoneTeeth IS NOT NULL
GROUP BY Name;

-- 确认无误后执行删除
DELETE FROM your_table_name
WHERE ID NOT IN (
    SELECT MAX(ID)
    FROM your_table_name
    WHERE FirstZoneTeeth IS NOT NULL 
        OR SecondZoneTeeth IS NOT NULL 
        OR ThirdZoneTeeth IS NOT NULL 
        OR FourthZoneTeeth IS NOT NULL
    GROUP BY Name
);

这里用MAX(ID)是保留每个用户最新的有效行,如果你想保留最早的,换成MIN(ID)即可。

方式2:用窗口函数更灵活排序

如果需要更复杂的优先级(比如同时考虑服务时间、数据完整性),窗口函数是更好的选择:

WITH ranked_records AS (
    SELECT 
        *,
        ROW_NUMBER() OVER (
            PARTITION BY Name 
            ORDER BY 
                -- 优先保留有牙齿数据的行
                CASE WHEN FirstZoneTeeth IS NOT NULL OR SecondZoneTeeth IS NOT NULL OR ThirdZoneTeeth IS NOT NULL OR FourthZoneTeeth IS NOT NULL THEN 0 ELSE 1 END,
                ID DESC -- 同优先级下保留最新的行
        ) AS row_rank
    FROM your_table_name
)
-- 先执行SELECT看要删除的行
SELECT * FROM ranked_records WHERE row_rank > 1;

-- 确认后删除
DELETE FROM your_table_name
WHERE ID IN (SELECT ID FROM ranked_records WHERE row_rank > 1);

重要提示

  • 记得把your_table_name替换成你实际使用的表名
  • 如果Name不是用户的唯一标识(比如有重名),要把分组依据换成用户的唯一ID字段
  • 执行删除操作前一定要先运行对应的SELECT语句验证,避免误删数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:39:53