2013-11-11 4 views
0

У меня сложная проблема sql. Позвольте мне qive вам примерНайти дубликаты из нескольких столбцов

ID1 Name  Name2 Name3 Name4 

100 Albert Kevin Jon  Alex 
101 Albert Jon  Kevin Alex 
102 Albert Georg Alex Babera 
103 Albert Stefany 

Lets говорят ID1 дает мне идентификатор проекта и имя является главным действующим лицом (Albert). Name2-4 являются подгруппами людей, которые работали с Альбертом. Теперь я хочу подсчитать совпадения между этими подгруппами. Сначала я хочу знать точные совпадения. Например, между 100 и 101. Во-вторых, можно ли подсчитать, сколько имен соответствует? Как один матч между 101 и 100.

Заранее спасибо

+3

Схема предназначена для того, чтобы сделать это невыносимо тяжелым. Нормализовать данные, и это будет проще (непросто, но проще). –

+0

Вы не поняли, факт, что в вашем примере (от 100 до 101) вы указываете, что существует только одно одно совпадение, означает, что вы хотите, чтобы позиция имени считалась так же, как и значение (все три имени находятся в обоих рядах где-то). Можете ли вы пояснить, что означает значение столбцов в этой схеме, и что именно вы пытаетесь сделать? –

+0

Я пытаюсь создать новый идентификатор, скажем, ID2, который будет иметь одинаковое значение для строк 100 и 101 и отличается для 102 и 103. – user2963882

ответ

0

Я знаю, что это долго и не пуленепробиваемым, но это своего рода делает работу.

WITH source_t AS 
(
     SELECT 100 id, 'Albert' name, 'Kevin' name2, 'Jon' name3, 'Alex' name4 FROM DUAL UNION ALL 
     SELECT 101, 'Albert',  'Jon',   'Kevin',  'Alex'  FROM DUAL UNION ALL 
     SELECT 102, 'Albert',  'Georg',  'Alex',  'Babera'  FROM DUAL UNION ALL 
     SELECT 103, 'Albert',  'Stefany',  NULL,   NULL  FROM DUAL 
) 
, tab_1 AS 
(
     SELECT id, name, name2 FROM source_t UNION ALL 
     SELECT id, name, name3 FROM source_t UNION ALL 
     SELECT id, name, name4 FROM source_t 
) 
, tab_2 AS 
(
     SELECT id 
     ,  name 
     ,  name2 
     ,  ROW_NUMBER() OVER (PARTITION BY id, name ORDER BY name2) AS r_number 
     FROM tab_1 
) 
, tab_3 AS 
(
     SELECT id 
     ,  name 
     ,  MAX(CASE WHEN r_number = 1 THEN name2 END) AS name2 
     ,  MAX(CASE WHEN r_number = 2 THEN name2 END) AS name3 
     ,  MAX(CASE WHEN r_number = 3 THEN name2 END) AS name4 
     FROM tab_2 
     GROUP BY 
       id 
     ,  name 
) 
SELECT tab_3.id 
,  tab_3.name 
,  tab_3.name2 
,  tab_3.name3 
,  tab_3.name4 
,  tab_4.n_count 
FROM tab_3 
LEFT JOIN 
(
     SELECT name 
     ,  name2 
     ,  name3 
     ,  name4 
     ,  COUNT(1) AS n_count 
     FROM tab_3 
     GROUP BY 
       name 
     ,  name2 
     ,  name3 
     ,  name4 
) tab_4 
ON  tab_3.name = tab_4.name 
and  NVL(tab_3.name2, 'NULL') = NVL(tab_4.name2, 'NULL') 
and  NVL(tab_3.name3, 'NULL') = NVL(tab_4.name3, 'NULL') 
and  NVL(tab_3.name4, 'NULL') = NVL(tab_4.name4, 'NULL') 
; 
/* 
102 Albert Alex Babera Georg 1 
103 Albert Stefany NULL NULL 1 
101 Albert Alex Jon  Kevin 2 
100 Albert Alex Jon  Kevin 2 
*/ 
Смежные вопросы