2017-08-14 7 views
0

私はこれをグーグルで試してみましたが、運はありません。私が見つけることができるすべての答えは、列全体で異なる情報であった。この場合、私は複数の列に同じ情報(電話番号)を持っています。同じ情報で異なる列間で重複を見つける

お客様と電話番号の表があります。各顧客は3つの異なる列(自宅、職場、携帯電話)で最大3つの異なる電話番号を持っています。移動電話番号は自宅番号として使用できます。彼らは夫と妻または親と子であるため、一部の顧客は他の顧客と同じ電話番号を持っています。この場合、これは問題ではありません。

したがって、私は、携帯電話と家の電話の両方の列で検索する必要があります。 (勤務先電話番号はここでは無視される。)

例テーブル:

ID/Phone home/Phone mobile 
1/12345678/98765432 
2/12345678/22222222 
3/23456789/33333333 
4/33333333/87654321 

を上記の表では、私はすべての4人の顧客を返すために、クエリが必要になります。同一の自宅の電話番号とID 3とID 4を持っているため、ID番号1とID 2は同じ番号(33333333)のホームとモバイルの列にあるためです。

少なくとも複製の顧客IDが必要ですが、重複した電話番号も確認したいと思います。

ありがとうございました!

答えて

1

私のアプローチは、重複を見つけるために、自己結合を行う、その後、ちょうどイドと携帯電話にクエリを正規化するために、次のようになります。

WITH [CTE] AS (
    SELECT Id, HomePhone as Phone FROM customers 
    UNION 
    SELECT Id, WorkPhone as Phone FROM customers 
    UNION 
    SELECT Id, MobilePhone as Phone FROM customers 
) 
SELECT c1.Id, c2.Id, [c1].[Phone] 
FROM [CTE] AS [c1] INNER JOIN [CTE] AS [c2] 
    ON [c1].[Phone] = [c2].[Phone] AND [c1].[Id] <> [c2].[Id] 
+0

ありがとうございます。これで私の問題は解決しました。私は前にこのようなものを試してみましたが、私は自分自身の内側結合部を得られませんでした。 – Mette

0

出力データの例を提供すると役に立ちます。 しかしEXISTSで試してみてください。https://msdn.microsoft.com/es-es/library/ms188336(v=sql.120).aspx

SELECT * 
FROM customers c 
WHERE EXISTS (SELECT * 
      FROM customers c2 
      WHERE c.Id != c2.Id 
      AND (
        (c.HomePhone = c2.HomePhone || c.HomePhone = c2.WorkPhone || c.HomePhone = c2.MobilePhone) 
        || (c.WorkPhone = c2.HomePhone || c.WorkPhone = c2.WorkPhone || c.WorkPhone = c2.MobilePhone) 
        || (c.MobilePhone= c2.HomePhone || c.MobilePhone= c2.WorkPhone || c.MobilePhone= c2.MobilePhone) 
      ) 
+0

は 'EXISTS' に向けて、私を指してくれてありがとう。私はそれを知らなかった。しかし、多くの重複が存在するため、問合せによって顧客表からすべての行が得られます。 – Mette

1

を、私はあなたがexists使ってやりたいことができると思います。

select t.* 
from t 
where exists (select 1 
       from t t2 
       where t2.id <> t.id and 
        (t2.homephone in (t.homephone, mobilephone) or 
        t2.mobilephone in (t.homephone, mobilephone) 
        ) 
      ); 
別のアプローチは、より良いパフォーマンスかもしれません

select tp.* 
from (select t.id, v.phone, 
      count(*) over (partition by id) as cnt 
     from t cross apply 
      (values (t.homephone), (t.mobilephone)) v(phone) 
    ) tp 
where cnt > 1; 

このバージョンでは、実際にします同じ電話を2つの列に持つ行を返します。これが問題になる可能性がある場合、これは簡単に修正されます。

+0

「存在」を指してくれてありがとう。私はそれを知らなかった。しかし、重複がたくさんあります。つまり、クエリは顧客テーブルからすべての行を取得するだけです。私は他の答えの一つに成功したので、クロス適用ソリューションを試しませんでした。 – Mette

1

あなたはデータをアンピボット可能性があり、その後、自己が参加します:

CREATE TABLE #phone 
(
    Id INT, 
    HomePhone VARCHAR(20), 
    MobilePhone VARCHAR(20) 
) 

INSERT INTO #phone (Id, HomePhone, MobilePhone) VALUES(1, 12345678, 98765432); 
INSERT INTO #phone (Id, HomePhone, MobilePhone) VALUES(2, 12345678, 22222222); 
INSERT INTO #phone (Id, HomePhone, MobilePhone) VALUES(3, 23456789, 33333333); 
INSERT INTO #phone (Id, HomePhone, MobilePhone) VALUES(4, 33333333, 87654321); 

WITH unpivoted AS 
(
    SELECT Id, Phone, PhoneType 
    FROM #phone 
    UNPIVOT 
    (
     Phone FOR PhoneType IN (HomePhone, MobilePhone) 
    ) AS unpiv 
) 
SELECT a.id, a.Phone, a.PhoneType, b.Id, b.Phone, b.PhoneType 
FROM unpivoted A 
INNER JOIN unpivoted B ON A.Phone = B.Phone AND B.Id > A.Id 

戻り

1 12345678 HomePhone 2 12345678 HomePhone 
3 33333333 MobilePhone 4 33333333 HomePhone 
+0

アンピボットソリューションを私に見せていただき、ありがとうございます。私はそれを以前は知らなかった。私は追加する必要があったwhere句でsomが困っていたので、これが私の最終結果に終わらなかったのです。 – Mette

関連する問題