2017-09-04 48 views
0

我想基於來自各個表的多個列來識別db中的重複項。在下面的示例中,1 & 5和2 & 4是重複的 - 因爲所有四列具有相同的值。如何使用sql識別這些記錄?當我必須根據單個列標識重複項時,我使用了> 1的計數,但我不確定如何根據多列標識它們。但是,我看到,當我根據所有4列進行計數> 1時,#3和#6顯示出來,它們在技術上不是按照我的要求重複的。基於多列識別重複項

T1

ID | Col1 | Col2 
---| --- | --- 
1 | A | US 
2 | B | FR 
3 | C | AU 
4 | B | FR 
5 | A | US 
6 | D | UK 

T2

ID | Col1 
---| ---    
1 | Apple 
1 | Kiwi 
2 | Pear 
3 | Banana 
3 | Banana 
4 | Pear 
5 | Apple 

T3

ID | Col1  
---| --- 
1 | Spinach 
1 | Beets 
2 | Celery 
3 | Radish 
4 | Celery 
5 | Spinach 
6 | Celery 
6 | Celery 

我的預期的結果將是:

1 A US Apple Spinach 
5 A US Apple Spinach 
2 B FR Pear Celery 
4 B FR Pear Celery 
+0

在組中使用'和condition' –

+0

您的預期結果是什麼? – zarruq

+0

更新了我的問題。 – Skn

回答

0

問題是您的結果集需要包含唯一的ID列。所以一個簡單的GROUP BY ... HAVING不會削減它。這會工作。

with cte as 
    (select t1.id 
       , t1.col1 as t1_col1 
       , t1.col2 as t1_col2 
       , t2.col1 as t2_col1 
       , t3.col1 as t3_col1 
     from t1 
      join t2 on t1.id = t2.id 
      join t3 on t1.id = t3.id 
    ) 
select cte.* 
from cte 
where (t1_col1, t1_col2, t2_col1, t3_col1) in 
     (select t1_col1, t1_col2, t2_col1, t3_col1 
     from cte 
     group by t1_col1, t1_col2, t2_col1, t3_col1 having count(*) > 1) 
/

的使用子查詢分解語法是可選的,但我覺得它有用的信號,即子查詢中使用一個以上的查詢。


「我所遇到的另一種情形中的數據,某些ID的在T2和T3相同的值,並且它們顯示爲的DUP」。

子表中重複的ID會導致連接子查詢中的笛卡爾積,這會在主結果集中導致誤報。理想情況下,您應該能夠通過在這些表上引入額外的過濾器來移除不需要的行。但是,如果數據質量這麼差,有沒有有效的規則,你將不得不求助於distinct

with cte as ( 
    select t1.id 
     , t1.col1 as t1_col1 
     , t1.col2 as t1_col2 
      , t2.col1 as t2_col1 
      , t3.col1 as t3_col1 
    from t1 
     join (select distinct id, col1 from t2) t2 on t1.id = t2.id 
     join (select distinct id, col1 from t3) t3 on t1.id = t3.id 
) ... 
+0

我在數據中遇到了另一種情況,其中一些ID在T2和T3中具有相同的值,並且它們顯示爲dups。 – Skn

+0

我這樣做了,請檢查ID 3和6. 3和6不是我的要求。 – Skn

0

可以group by子句中添加的所有列,而您要查找的重複和然後寫入計數條件中有聖誕老人

select t1.id,t1.col1,t2.col2,t2.col3,t3.col4 from t1 join t2 on t1.id=t2.id join t3 on t3.id=t1.id where (t1.col1,t2.col2,t2.col3,t3.col4) in (
    select t1.col1,t2.col2,t2.col3,t3.col4 
    from t1 join t2 on t1.id=t2.id join t3 on t3.id=t1.id 
    group by t1.col1,t2.col2,t2.col3,t3.col4 
    having count(*) >1 ) 
+0

你已經跳過了加入多個表的問題。這意味着您的解決方案無法處理數據中的其他褶皺。 – APC

+0

@APC OP並沒有在第一時間提到no.of表,他在2小時後改變了它。總之我會相應地改變它 – Rams

0

爲了您的樣本數據,你可以使用這個所有inner join-ing三個表,並使用如下,在短短group by tA.Col1 having count(tA.Col1)>1where條款子查詢,以獲得您想要的結果實現。

SELECT t1.ID, 
     t1.Col1, 
     t1.Col2, 
     t2.Col1, 
     t3.Col1 
FROM table1 t1 
JOIN table2 t2 ON t1.ID = t2.ID 
JOIN table3 t3 ON t1.ID = t3.ID 
WHERE t1.Col1 IN 
    (SELECT tA.Col1 
    FROM table1 tA 
    GROUP BY tA.Col1 
    HAVING count(tA.Col1)>1) 
ORDER BY t1.ID; 

結果

ID Col1 Col2 Col1 Col1 
----------------------------------- 
1 A  US  Apple Spinach 
2 B  FR  Pear Celery 
4 B  FR  Pear Celery 
5 A  US  Apple Spinach 

您可以查看演示here

希望這會有所幫助。

+0

這個解決方案只有在't1.col1'和't1 .col2'。我同意適用於發佈的樣本測試數據,但是您假設它適用於真實數據 – APC

+0

@APC:這就是爲什麼我的答案的第一行是「對於您的示例數據」:-) – zarruq