2013-08-13 6 views
0

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

Вот пример, показывающий, что я хочу сделать

Table 1      Table 2 

ID  DuplicateId   ID  MD5 (Pretend these are correct) 
1  Null     1  25622 
2  Null     2  25622 
3  Null     3  86548 
4  Null     4  86548 

Конечный результат запроса должен дать мне этот

Table 1 

ID  DuplicateId 
1  
2  1 
3  
4  3 

Это довольно простой пример, но это лучшее, что я может придумать, чтобы объяснить мою ситуацию. Конечная цель в значительной степени зависит от ребенка/родителя, если вы хотите об этом думать. Любая помощь будет принята с благодарностью.

+0

Что произойдет, если в таблице 2 есть дубликат для MD5 = 25622 ?. – Lamak

+0

найдите предложение HAVING COUNT (*), а также функции LAG – Randy

+0

@Lamak, если есть еще один дубликат для 25622, тогда он также получит значение 1 в таблице 1. Мне нужна только первая запись, каждый раз, когда она хранится в моей базе данных – hav2play21

ответ

2

Вы можете получить то, что вы хотите с этим запросом :

select t2a.id, (case when t2a.id <> min(t2b.id) then min(t2b.id) end) as DuplicateId 
from Table2 t2a left outer join 
    Table2 t2b 
    on t2a.MD5 = t2b.MD5 
group by t2a.id; 

более эффективный способ реализовать это:

select id, (case when id <> minid then minid end) as DuplicateId 
from (select t.*, min(id) over (partition by MD5) as minid 
     from Table2 t 
    ) t 

Если вам действительно нужно это в другой таблице, вы можете использовать select into или insert.

+2

В вашем втором запросе вы сравниваете 'id' с' MD5', который не будет работать – Lamak

+0

@Lamak. , , Спасибо. –

+0

@ Ламак, спасибо Гордону и Ламаку за сообщение и исправления. Второе решение, которое вы предоставили, отлично работало. – hav2play21

1

Используйте CTE для вычисления номера строки для каждого подобного MD5. Затем получить идентификатор первого вхождения из MD5s и обновление таблицы 1.

;WITH ResultCTE AS 
(
    SELECT ID, 
       MD5, 
       ROWNUMBER() OVER (PARTITION BY MD5 ORDER BY ID) AS RowNum 
    FROM  Table2 
) 
UPDATE Table1 
SET DuplicateID = CASE 
         WHEN T1.ID = T2.ID 
         THEN NULL ELSE T2.ID 
        END 
FROM Table1 T1 
     JOIN Table2 T3 
      ON T1.ID = T3.ID 
     JOIN (
       SELECT ID, 
         MD5 
       FROM ResultCTE 
       WHERE RowNum = 1 
      ) T2 
      ON T1.MD5 = T2.MD5 

Если Table1 не имеет значения, первоначально то:

;WITH ResultCTE AS 
(
    SELECT ID, 
       MD5, 
       ROWNUMBER() OVER (PARTITION BY MD5 ORDER BY ID) AS RowNum 
    FROM  Table2 
) 
INSERT INTO Table1 
SELECT T1.ID, 
      CASE 
       WHEN T1.ID = T2.ID 
       THEN NULL ELSE T2.ID 
      END AS DuplicateID 
FROM   Table2 T1 
     JOIN (
       SELECT ID, 
         MD5  
       FROM   ResultCTE  
       WHERE  RowNum = 1 
      ) T2 
      ON T1.MD5 = T2.MD5 
+1

'ROW_NUMBER()' typo –

+1

Проблема, которую я вижу здесь, заключается в том, что в таблице 1 нет сохраненного MD5, только в таблице 2, как показано выше. Я что-то упускаю? – hav2play21

+0

Имеет ли таблица 1 значения первоначально? –