TSQL:如果我的行中存在的值等于另一列中可能存在的另一行的相同值,如何更新一列

时间:2017-01-05 21:21:41

标签: sql-server tsql merge duplicates sql-update

我正在使用SQL Server 2012版本11.0.6020.0。提前道歉,我是SQL的新手。

我有一张人名表。由于重复,一个人可以有多个ID。为了清理它,创建了一个主ID。但是,仍然存在重复。目前,它看起来像这样......

IF OBJECT_ID('tempdb..#table1') IS NOT NULL
BEGIN
    DROP TABLE #table1
END

CREATE TABLE #table1 (MasterID varchar(1), PersonID1 varchar(3), PersonID2 varchar(3), PersonID3 varchar(3), PersonID4 varchar(3), PersonID5 varchar(3))

INSERT INTO #table1 VALUES ('A', '12', '34', '56', '78', null);
INSERT INTO #table1 VALUES ('B', '34', '12', '90', null, null);
INSERT INTO #table1 VALUES ('C', '777', '888', null, null, null);

执行上面的代码时,表格如下所示。

+----------+-----------+-----------+-----------+-----------+-----------+
| MasterID | PersonID1 | PersonID2 | PersonID3 | PersonID4 | PersonID5 |
+----------+-----------+-----------+-----------+-----------+-----------+
| A        |        12 |        34 |        56 |        78 |           |
| B        |        34 |        12 |        90 |           |           |
| C        |       777 |       888 |           |           |           |
+----------+-----------+-----------+-----------+-----------+-----------+

MasterID A和MasterID B是同一个人,因为某些PersonID重叠。 MasterID C是一个不同的人,因为它不共享任何ID。如果共享一个ID,那么我可以认为它是同一个患者。所以我想要的输出是......

+----------+-----------+-----------+-----------+-----------+-----------+
| MasterID | PersonID1 | PersonID2 | PersonID3 | PersonID4 | PersonID5 |
+----------+-----------+-----------+-----------+-----------+-----------+
| A        |        12 |        34 |        56 |        78 |        90 |
| C        |       777 |       888 |           |           |           |
+----------+-----------+-----------+-----------+-----------+-----------+

我考虑过对数据进行拆分并对其进行分组。

IF OBJECT_ID('tempdb..#t1') IS NOT NULL
BEGIN
    DROP TABLE #t1
END

SELECT MasterID, PersonID
INTO #t1
FROM
(
    SELECT MasterID, PersonID1, PersonID2, PersonID3, PersonID4, PersonID5
    FROM #table1
) t1
UNPIVOT
(
    PersonID FOR PersonIDs IN (PersonID1, PersonID2, PersonID3, PersonID4, PersonID5)
) AS up

GO

---------------------------------------------------

SELECT min(MasterID) as MasterID, PersonID
FROM #t1
GROUP BY PersonID
ORDER BY 1, 2

然而,这个解决方案将让我在下面看到90就是它自己的人。

+----------+-----------+
| MasterID | PersonID  |
+----------+-----------+
| A        |        12 |
| A        |        34 |
| A        |        56 |
| A        |        78 |
| B        |        90 |
| C        |       777 |
| C        |       888 |
+----------+-----------+

我查看了堆栈溢出,我找到的最接近的解决方案是这个,但它涉及两个表,而我的是在同一个表中 SQL UPDATE SET one column to be equal to a value in a related table referenced by a different column?

我也发现了这一点,但最大聚合函数可能对我的情况不起作用。 Merge two rows in SQL

这个解决方案看起来会起作用,但它需要我在更新MasterID之前先手动检查每个字段是否有重复的PersonID。 set a row equal to another row in the same table apart the primary key column

我的目标是对重复项进行SQL检查,如果找到,请删除重复项并更新添加新的PersonID。至于使用哪个masterID,我是否保留A或B并不重要。

如果您知道任何解决方案或者可以指导我,请告诉我。我是SQL的新手,所以我可能会搜索错误的关键字和词汇表。谢谢,我真的很感激!

1 个答案:

答案 0 :(得分:1)

请尝试以下查询。它会添加MainMasterID列以标识每条记录的主MasterID

select *, 
       (select min(MasterID) 
          from #table1 t2 
         where t1.PersonID1 in (t2.PersonID1, t2.PersonID2, t2.PersonID3, t2.PersonID4, t2.PersonID5)
            or t1.PersonID2 in (t2.PersonID1, t2.PersonID2, t2.PersonID3, t2.PersonID4, t2.PersonID5)
            or t1.PersonID3 in (t2.PersonID1, t2.PersonID2, t2.PersonID3, t2.PersonID4, t2.PersonID5)
            or t1.PersonID4 in (t2.PersonID1, t2.PersonID2, t2.PersonID3, t2.PersonID4, t2.PersonID5)
            or t1.PersonID5 in (t2.PersonID1, t2.PersonID2, t2.PersonID3, t2.PersonID4, t2.PersonID5)
         ) AS MainMasterID
 from #table1 t1

/* Sample data output

MasterID PersonID1 PersonID2 PersonID3 PersonID4 PersonID5 MainMasterID
-------- --------- --------- --------- --------- --------- ------------
A        12        34        56        78        NULL      A
B        34        12        90        NULL      NULL      A
C        777       888       NULL      NULL      NULL      C

*/