2014-10-22 5 views
3

Я пытаюсь найти информацию о том, как дедуплировать таблицу на основе количества совпадающих столбцов между записями.SQL dedupe на основе количества сопоставимых столбцов

Допустим, мой источник данных выглядит

--------------------------------------------------- 
| 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. Есть 0 записей, которые соответствуют на 5 колонок
  2. Есть 1 записей, которые соответствуют на 4 колонки (3,5)
  3. Имеются 1 записи, которые соответствуют по 3 колонкам (1,6) (3,5)
  4. Имеются 2 записи, которые соответствуют по 2 столбца (1,6) (2,6) (3,5) (1 , 2)

Мне также понадобится, чтобы он «сдвигался» вниз, так как количество согласованных столбцов становилось все меньше и меньше. Таким образом, в приведенных выше данных мои данные совпадают после проверки соответствия пяти столбцов. Затем на 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-я колонна ушла, потому что это было deduped (я понятия не имею, как я решил, который был удален, вероятно, на какой дате колонке). Поэтому я могу сказать, что 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 удаляется.

Затем 2 колонки:

--------------------------------------------------- 
| ColumnA | ColumnB | ColumnC | ColumnD | ColumnN | 
--------------------------------------------------- 
| Peter | Dink | Midget | NULL | 0738455 | 
| Mark | Walhg | Funky | 334AA | 0738455 | 
| Mark | Dink | NULL | NULL | NULL | 
--------------------------------------------------- 

Другой столбец удаляется.

Как я думал, я бы приблизился к этому, предоставив вес, это по существу количество совпадающих точек данных из выбора столбцов. Например, возможно, я бы не хотел использовать столбец «Страна» для подсчета в качестве одного из соответствующих столбцов, я бы использовал только те, которые идентифицируют запись, такую ​​как «Имя и номер телефона».

Затем я могу посмотреть, сколько записей выводится на каждый вес (количество совпадений столбцов) и принять решение о том, что мы будем дедуплировать все с 7 соответствующими столбцами данных идентификации; и сверните любые значения в одной записи, которые имеют NULL/blank в дубликатной записи.

Это все очень далеко от меня. Я знаю, что хочу делать; просто не знаю, как это сделать.

ответ

1

Надеюсь, я правильно понял вас. Это мое представление о том, как это можно сделать, но не полностью, вы можете автоматизировать его с помощью динамического sql и цикла while, чтобы пройти через все идентификаторы и унифицировать результаты позже.

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 
) 
+0

Не совсем то, что я имел в виду. Используя вышеизложенное, я могу создавать петли и находить записи, соответствующие каждой записи, на основе двух соответствующих столбцов (с небольшим изменением + добавлением). Однако, как только у меня есть это, я не уверен, как я смогу объединить все результаты? – NeomerArcana

+0

Вы можете поместить их в таблицы переменных, таблицы temp, исходные таблицы, представления, создать процедуру, в которой вы пишете имя таблицы и столбцы, которые вы хотите дедупментировать .. что-то вроде этого: P – SubqueryCrunch