2017-09-04 17 views
0

さまざまなテーブルの複数の列に基づいて、データベース内の重複を識別したい。下の例では、1 & 5と2 & 4が重複しています.4つの列がすべて同じ値を持つためです。どのように私はSQLを使用してそのようなレコードを特定するのですか? 1つの列に基づいて重複を特定する必要があるときにcount> 1を持つグループを使用しましたが、複数の列に基づいてそれらを識別する方法がわかりません。しかし、4列すべてに基づいてcount> 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

グループで 'and 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

あなたが重複を見つけるしたいgro​​up 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は最初の例ではテーブルの数は言及していませんでしたが、それはほぼ2時間後に変更されました...とにかく私はそれに応じて変更します – Rams

0

を有する点でカウント条件を書き、あなたはこのinner join-ingすべての3つのテーブルを使用して、所望の結果を得るために、以下のようにちょうど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

関連する問題