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

SQL Server视图如何去除单列重复值且不修改源表数据

问题根因

你之前写的自连接去重逻辑有两个核心错误,导致无法生效:

  1. 比较字段写错:PS2.LSiteID < PS.LSiteID是用重复维度本身做大小比较,同一个LSiteID对应的多条记录该字段值完全相等,这个条件永远不会成立,子查询计数恒为0,等于没有加过滤规则。
  2. 子查询没有关联外层查询的匹配逻辑,也没有引入唯一字段做判断基准,本身逻辑闭环不成立。
推荐实现方案

用窗口函数ROW_NUMBER()是SQL Server下这类视图层按指定字段去重的最优方案,不会修改源表任何数据,性能也比自连接写法更好。逻辑是按LSiteID分区,借助你提到的全局唯一的ProjectNumber做排序基准,每个LSiteID分组只保留1条记录即可。
可直接替换原视图的创建语句:

CREATE VIEW dbo.v_LSitesGeo AS
SELECT LSiteID, geographyColumn
FROM (
    SELECT 
        PS.LSiteID, 
        GEO.geographyColumn,
        ROW_NUMBER() OVER (
            PARTITION BY PS.LSiteID 
            ORDER BY PS.ProjectNumber -- 同LSiteID下默认取ProjectNumber最小的关联记录,需要倒序取最新的就在字段后加DESC
        ) AS row_seq
    FROM dbo.Project_SiteID_Lookup AS PS 
    INNER JOIN dbo.Geocodio AS GEO 
        ON GEO.ProjectCode = PS.ProjectNumber
    WHERE GEO.geographyColumn IS NOT NULL 
      AND PS.LSiteID IS NOT NULL
) AS filtered
WHERE row_seq = 1

方案说明

  • 该写法完全在视图层实现过滤,源表Project_SiteID_Lookup的重复数据不会做任何改动,符合你的要求。
  • 如果对同一个LSiteID下保留哪条地理数据有明确规则,只需要修改窗口函数里ORDER BY后的字段即可,比如需要保留最新创建的记录,就换成表内的创建时间字段倒序排序。
  • 之所以不能直接用DISTINCT,是因为DISTINCT会对LSiteID+geographyColumn的组合去重,如果同一个LSiteID对应不同的geographyColumn值,依然会返回重复的LSiteID,达不到按LSiteID维度去重的目的。
原自连接写法的修正版

如果你习惯用类同你之前尝试的自连接逻辑,可以用NOT EXISTS改写(性能比COUNT计数好),核心是把比较字段换成唯一的ProjectNumber:

CREATE VIEW dbo.v_LSitesGeo AS
SELECT PS.LSiteID, GEO.geographyColumn
FROM dbo.Project_SiteID_Lookup AS PS 
INNER JOIN dbo.Geocodio AS GEO 
    ON GEO.ProjectCode = PS.ProjectNumber
WHERE GEO.geographyColumn IS NOT NULL 
  AND PS.LSiteID IS NOT NULL
  AND NOT EXISTS (
      SELECT 1
      FROM dbo.Project_SiteID_Lookup AS PS2
      WHERE PS2.LSiteID = PS.LSiteID
        AND PS2.ProjectNumber < PS.ProjectNumber -- 同LSiteID下只保留ProjectNumber最小的记录
  )

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:15:29