基于匹配列数量的SQL去重

3
“我正在尝试查找有关如何根据记录之间匹配列的数量对表进行去重的信息。
假设我的数据源看起来像这样。”
---------------------------------------------------
| ColumnA | ColumnB | ColumnC | ColumnD | ColumnN |
---------------------------------------------------
| Peter   | Dink    | Midget  | NULL    | 0738455 |
| Peter   | Dink    | Child   | 334AA   | 49595   |
| Mark    | Walhg   | Funky   | 334AA   | 0738455 | 
| Mark    | Dink    | NULL    | NULL    | NULL    |
| Mark    | Walhg   | Funky   | 334AA   | NULL    |
| Peter   | Dink    | NULL    | NULL    | 0738455 |
---------------------------------------------------

基本上,我想能够提供共享2、3、4等列数据的记录计数;但是,我需要将其限制在仅选择的一部分列中(并忽略NULL/空白)。
从上面的数据中,我想要能够说:
1. 没有匹配5列的记录。 2. 有1个记录匹配了4列(3,5)。 3. 有1个记录匹配了3列(1,6)(3,5)。 4. 有2个记录匹配了2列(1,6)(2,6)(3,5)(1,2)。
我还需要它随着匹配的列数越来越少而“向下”移动。因此,在检查5列的匹配后,我的数据仍然相同。然后,在4列上,数据减少为:
---------------------------------------------------
| ColumnA | ColumnB | ColumnC | ColumnD | ColumnN |
---------------------------------------------------
| Peter   | Dink    | Midget  | NULL    | 0738455 |
| Peter   | Dink    | Child   | 334AA   | 49595   |
| Mark    | Walhg   | Funky   | 334AA   | 0738455 | 
| Mark    | Dink    | NULL    | NULL    | NULL    |
| Peter   | Dink    | NULL    | NULL    | 0738455 |
---------------------------------------------------

第5列已被去重,因此消失了(我不知道我是如何决定删除哪个列的,可能是在某个日期列上)。所以我可以说有1条记录被删除了。
在对3列进行检查后:
---------------------------------------------------
| ColumnA | ColumnB | ColumnC | ColumnD | ColumnN |
---------------------------------------------------
| Peter   | Dink    | Midget  | NULL    | 0738455 |
| Peter   | Dink    | Child   | 334AA   | 49595   |
| Mark    | Walhg   | Funky   | 334AA   | 0738455 | 
| Mark    | Dink    | NULL    | NULL    | NULL    |
---------------------------------------------------

所以我可以说又移除了1个。
然后是两列:
---------------------------------------------------
| ColumnA | ColumnB | ColumnC | ColumnD | ColumnN |
---------------------------------------------------
| Peter   | Dink    | Midget  | NULL    | 0738455 |
| Mark    | Walhg   | Funky   | 334AA   | 0738455 | 
| Mark    | Dink    | NULL    | NULL    | NULL    |
---------------------------------------------------

另一列被移除了。
我想处理它的方式是给一个权重,这个权重基本上是选择的列中匹配数据点的数量。例如,也许我不想使用国家列作为匹配列之一,我只想使用像姓名和电话号码这样可以识别记录的东西。
然后我可以查看每个权重(列匹配数)有多少记录被去重,并决定我们将去重所有具有7个匹配身份数据列的内容;并在其中一个记录中卷起任何空/空白的值。
这对我来说都很复杂。我知道我想做什么,只是不知道该怎么做。
1个回答

1

我希望我理解你的意思是正确的。这是我关于如何完成这个任务的想法,它还不完整,你可以使用动态SQL和while循环来自动化处理所有ID,并在后面统一结果。

IF OBJECT_ID('TestTable1') IS NOT NULL 
DROP TABLE TestTable1

CREATE TABLE TestTable1 (
    ID INT IDENTITY(1,1),
    ColumnA NVARCHAR(100),
    ColumnB NVARCHAR(100),
    ColumnC NVARCHAR(100),
    ColumnD NVARCHAR(100),
    ColumnE INT
)

INSERT INTO TestTable1 VALUES 
('Peter','Dink','Milk',NULL,0738455),
('Peter','Dink','Beer','334AA',49595),
('Mark','Walk','Funky','334AA',0738455),
('Mark','Dink',NULL,NULL,NULL),
('Mark','Walk','Funky','334AA',NULL),
('Peter','Dink',NULL,NULL,0738455)

DECLARE @ID INT
SET @ID = 1

SELECT * FROM TestTable1 WHERE ID IN 
(
    SELECT ID FROM
    (   
        SELECT @ID AS ID
        UNION
        SELECT b.ID FROM TestTable1 as a
        CROSS APPLY TestTable1 as b
        WHERE a.ColumnA = b.ColumnA
        AND a.ID = @ID AND b.ID <> @ID
    ) AS OneMatchingColumn
) 


SELECT * FROM TestTable1 WHERE ID IN 
(
    SELECT ID FROM
    (
        SELECT @ID AS ID
        UNION
        SELECT b.ID FROM TestTable1 as a
        CROSS APPLY TestTable1 as b
        WHERE a.ColumnA = b.ColumnA
        AND a.ColumnB = b.ColumnB
        AND a.ID = @ID AND b.ID <> @ID
    ) AS TwoMatchingColumns
)


SELECT * FROM TestTable1 WHERE ID IN 
(
    SELECT ID FROM
    (
        SELECT @ID AS ID
        UNION
        SELECT b.ID FROM TestTable1 as a
        CROSS APPLY TestTable1 as b
        WHERE a.ColumnA = b.ColumnA
        AND a.ColumnB = b.ColumnB
        AND a.ColumnC = b.ColumnC
        AND a.ID = @ID AND b.ID <> @ID
    ) AS ThreeMatchingColumns
)

不太符合我的想法。使用上述方法,我可以循环并查找基于任何两个匹配列的每个记录匹配的记录(稍作更改和添加)。但是,一旦我拥有了这些结果,我不确定如何将它们合并? - NeomerArcana
你可以将它们放在变量表、临时表、原始表、视图中,或者编写一个过程,在其中写入你想要去重的表名和列名等。就像这样:P - SubqueryCrunch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接