更新特定的重复条目

时间:2019-02-24 00:42:07

标签: sql sql-server duplicates foreign-keys

在我的SQL表中,我试图编写一个存储过程,该过程将在每个表中查找重复项,并在找到特定列时更新true或false。由于使用了外键,所以这有点复杂,我不确定最好的写法。

目标:在表A中,如果满足重复条件,则将列“ isDuplicates”(均以FALSE开始)更新为TRUE

外键:数据库中的每个表都包含来自源资料的数据,每个数据都有发布日期。没有包含SourceDate的Sources表。每个其他表都有一个Sources列,该列带有一个外键,该外键映射到它在Sources表上的条目,使我可以访问日期。

重复条件:在表A中,如果存在其他任何同名(列“ Name”)的条目(不同的主键“ Id”),另一个条目是重复项该条目稍后发布(外键。SourceDate大于当前条目)

最终,我试图创建一个表,其中'isDuplicate'= TRUE表示存在一个具有相同名称/不同ID的重复项,而另一项则在以后发布。因此,如果某样东西是重复的,但它本身就是最新版本,则应该说“ isDuplicate” = FALSE

希望这是有道理的。谢谢大家。

编辑:使用示例进行更新。

表A 具有列 NAME SOURCE ISDUPLICATE

Frank 71 False
Tom 71 False
Tom 83 False
Richard 83 False
Frank 13 False

SOURCES 表具有列 ID SOURCEDATE

13 2/1/2010
71 5/1/2014
83 8/1/2014

表A 上运行存储过程后,我期望得到以下结果:

Frank 71 False
Tom 71 True
Tom 83 False
Richard 83 False
Frank 13 True

Frank(来源13)和Tom(71)都被标记为TRUE,因为它们是另一个现有条目的旧版本。我将Tom(83)和Frank(71)设为FALSE,因为它们是我要显示的主要条目。

不仅仅是删除重复项的目的是允许用户使用功能-默认情况下,他们只会为每件商品看到一个条目,并且它将始终是最新发布的商品。但是,我还将允许他们查看他们想要的所有内容(基本上默认为仅使用isDuplicate = FALSE提取数据,但允许他们将其关闭并显示重复/旧数据)。

1 个答案:

答案 0 :(得分:1)

我认为以下查询应能为您提供所需的信息。它通过联接表tableASources来工作。内联相关子查询可用于检查记录是否被视为重复项:

SELECT t.Name, t.Source, CASE WHEN EXISTS (
    SELECT 1 
    FROM tableA t1 
    INNER JOIN Sources s1 ON s1.ID = t1.Source
    WHERE t1.Name = t.Name AND s1.SourceDate < s.SourceDate
    ) THEN 1 ELSE 0 END AS isDuplicate
FROM tableA
INNER JOIN Sources s ON s.ID = t.Source

isDuplicate列的值为0(非重复)或1(重复)


对于SQLServer 2017,使用窗口函数ROW_NUMBER()

SELECT 
    t.Name, 
    t.Source, 
    CASE 
        WHEN ROW_NUMBER() OVER(PARTITION BY t.Name ORDER BY s.SourceDate DESC) = 1 THEN 0
        ELSE 1
    END AS isDuplicate
FROM tableA t
INNER JOIN Sources s ON s.ID = t.Source

您可以将其放入CTE,然后将其转换为更新查询:

WITH cte AS (
    SELECT 
        t.*,
        ROW_NUMBER() OVER(PARTITION BY t.Name ORDER BY s.SourceDate DESC) AS rn
    FROM tableA t
    INNER JOIN Sources s ON s.ID = t.Source
) UPDATE cte SET isDuplicate = IIF(rn = 1, 0, 1)