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

SQL Server中用UNION和ROW_NUMBER获取两表唯一Name值问题

解决你的SQL Server去重问题:UNION + ROW_NUMBER()异常排查与修复

嘿,我看你遇到了用ROW_NUMBER()和UNION提取唯一Name记录的问题,结果里Clare S的RN居然到了52,取RN=1时还没显示,这确实挺头疼的。咱们一步步来分析和解决:

问题根源排查

从你给出的rn>0结果来看,同一个Name出现了多个RN值(比如Clare S有RN=52和RN=1),大概率是以下两个原因:

  • 字符串不一致:View1的Title和Table2的Name可能存在细微差异,比如前后空格、大小写不同(比如Clare S和Clare S 或者clare s),SQL Server默认会把这些当成不同的字符串,导致分区的时候被分到不同组,自然会生成多个RN=1的记录。
  • 原始数据中该Name存在大量重复:比如Clare S在cte1里实际有52条记录,所以RN会从1排到52,而你只看到了其中两条。

修复方案

方案1:统一字符串格式(解决最可能的字符串差异问题)

先对Name字段做归一化处理,去除前后空格并统一大小写,确保两个来源的字符串完全一致,再进行分区:

WITH cte1 AS (
    -- 处理View1的数据,保留原始Name同时生成归一化版本
    SELECT 
        ID, 
        Caseid, 
        Title AS OriginalName,
        LTRIM(RTRIM(LOWER(Title))) AS NormalizedName
    FROM View1 
    UNION ALL -- 用UNION ALL比UNION高效,因为后续会用ROW_NUMBER去重,不需要提前去重
    -- 处理Table2的数据
    SELECT 
        ID, 
        CaseID, 
        Name AS OriginalName,
        LTRIM(RTRIM(LOWER(Name))) AS NormalizedName
    FROM Table2 
    WHERE Party = 'Yes'
),
cte2 AS (
    SELECT 
        ID, 
        Caseid, 
        OriginalName,
        -- 按归一化后的Name分区,按ID倒序取最新的一条
        ROW_NUMBER() OVER (PARTITION BY NormalizedName ORDER BY ID DESC) AS rn
    FROM cte1
)
-- 只取每个归一化Name的第一条记录
SELECT 
    ID, 
    Caseid, 
    OriginalName AS Name
FROM cte2 
WHERE rn = 1

方案2:用GROUP BY快速取唯一记录(如果不在乎取哪条ID)

如果你的业务允许任意保留同一个Name的一条记录(比如取最大ID的那条),可以直接用GROUP BY,写法更简洁:

SELECT
    MAX(ID) AS ID, -- 换成MIN(ID)可以取最早的记录
    MAX(Caseid) AS Caseid, -- 从你的数据看同一个Name的Caseid都是相同的,MAX/MIN都可以
    -- 这里用归一化后的Name分组,避免字符串差异
    LTRIM(RTRIM(LOWER(Name))) AS Name
FROM (
    SELECT ID, Caseid, Title AS Name FROM View1
    UNION ALL
    SELECT ID, CaseID, Name AS Name FROM Table2 WHERE Party = 'Yes'
) t
GROUP BY LTRIM(RTRIM(LOWER(Name)))

验证方法:先确认Name的重复情况

你可以先跑下面的SQL,看看每个Name的实际记录数,以及是否有看起来相同但实际不同的字符串:

SELECT
    Name,
    COUNT(*) AS RecordCount,
    MIN(ID) AS MinID,
    MAX(ID) AS MaxID
FROM (
    SELECT ID, Caseid, Title AS Name FROM View1
    UNION ALL
    SELECT ID, CaseID, Name AS Name FROM Table2 WHERE Party = 'Yes'
) t
GROUP BY Name
ORDER BY RecordCount DESC

如果看到有多个看起来一样的Name(比如Clare S和Clare S ),那就是字符串差异的问题,用方案1的归一化处理就能解决。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:42:05