Найти дубликаты записей в SQL Server, а также вернуть набор уникальных ключей каждого - PullRequest
0 голосов
/ 19 мая 2018

У меня есть база данных SQL Server с уникальным ключевым столбцом и 49 столбцами элементов данных (имя / адрес / и т. Д. ......).У меня есть «дубликаты» записей, но с разными ключами, и я хочу найти эти дубликаты записей.

Например, у меня может быть «Джон Смит» (с 47 другими столбцами информации) в таблице дважды.Обе записи Джона Смита будут иметь разные столбцы уникальных ключей, но в остальном все остальные столбцы будут идентичны.В том числе, если один из столбцов равен NULL, то он будет равен NULL для обеих записей Джона Смита.

Чтобы усложнить ситуацию, есть две таблицы, которые мне нужно объединить, а затем, при объединении, найти любые записи, где элементы данных(все, кроме ключа) одинаково.

макет таблицы 1

MyKey, table2ID, Col1, Col2, Col3....Col46.

макет таблицы 2

ID, col47, col48, col49

от Col1 до Col49 - это место, где «дублируются» данныеможет быть.

Я пробовал что-то вроде ниже, что почти работает.Сбой, если у меня есть значения NULL.Например, если Col22 равно NULL для обеих записей Джона Смита (т.е. они оба имеют одинаковое значение NULL), то они не будут выбраны при выборе.

Вопрос: как мне получитьчто-то вроде ниже, чтобы работать, даже когда есть значения NULL, которые нужно сравнивать друг с другом.

with MyJoinedTable as
(
    select PolicyNumber, col01, col02, col03......col49
    from table1
    inner join table2 on table2id = table2.id
)
select PolicyNumber, t1.col01, t1.col02, t1.col03.......t1.col49
from MyJoinedTable t1
inner join (select col01, col02, col03......col49
            from MyJoinedTable
            group by col01, col02, col03......col49
            having count(*) > 1) t2 
      on t1.col01 = t2.col01
      and t1.col02 = t2.col02
      .......
      and t1.col49 = t2.col49
order by t1.col01, t1.col02

Ответы [ 2 ]

0 голосов
/ 19 мая 2018

Сгруппируйте в подзапрос с помощью HAVING count(*) > 1 и присоедините его обратно.

SELECT to1.policynumber,
       to1.col1,
       ...
       to1.col49
       FROM elbat to1
            INNER JOIN (SELECT ti.col1,
                               ...
                               ti.col49
                               FROM elbat ti
                               GROUP BY col1,
                                        ...
                                        col49
                               HAVING count(*) > 1) to2
                       ON to2.col1 = to1.col1
                          ...
                          AND to2.col49 = to1.col49;

Или используйте EXISTS.

SELECT to.policynumber,
       to.col1,
       ...
       to.col49
       FROM elbat to
       WHERE EXISTS (SELECT *
                            FROM elbat ti
                            WHERE ti.policynumber <> to.policynumber
                                  AND ti.col1 = to.col1
                                  ...
                                  AND ti.col49 = to.col49);
0 голосов
/ 19 мая 2018

Один из методов:

select t.*
from t
where exists (select 1
              from t t2
              where t2.col1 = t.col1 and
                    t2.col2 = t.col2 and
                    . . .
                    t2.policyNumber <> t.policyNumber
             );

Это работает при условии, что ни один из других столбцов не является NULL.

РЕДАКТИРОВАТЬ:

Если вы используете SQL ServerЯ бы просто сделал:

select t.*
from (select t.*,
             min(id) over (partition by col1, col2, . . . ) as min_id,
             max(id) over (partition by col1, col2, . . . ) as max_id
      from t
     ) t
where minid <> maxid;
...