2016-08-15 5 views
3

「より完全な」重複を選択するSQLクエリを作成しようとしています。たとえば、テーブルに次の4つのフィールドが含まれている場合:Name、Phone、Email、CompanyId、および両方Name & CompanyIdは2つのレコードで同じですが、そのうちの1つにPhoneおよび/またはEmailが含まれ、完了したレコードのみがレコードセットで使用可能になります。「より完全な」重複レコードを選択するクエリ

私はクエリがダウンしたと思ったが、 "より完全な"レコードが存在しない場合、そのレコードは完全に削除されるか、レコードセットに複製されたままになります。データの損失や重複を引き起こさない、これを実行するためのより良い方法があるかどうかはわかりません。今私が思うことができるのは、UNIONより多くの他のクエリですが、よりよい方法が必要だと感じています。私は生のデータを取得するために、CTEを使用して、ここで私は重複を削除するためにそれを操作するために何をしようとしているのですよ。

;WITH Contacts AS ( 
    -- LONG QUERY HERE THAT UNIONS NECESSARY Tables & XML Columns AND returns a recordset with Name, Email, Phone, and ClientId 
) 
SELECT u.* FROM Contacts u 
INNER JOIN (
    SELECT Name, ClientId, Count(*) AS ct FROM Contacts 
    GROUP BY Name, ClientId 
    HAVING COUNT(*) > 1 
) AS g 
ON u.Name = g.Name AND u.ClientId = g.ClientId 
WHERE Phone IS NOT NULL AND Email IS NOT NULL 
UNION 
SELECT u.* FROM Contacts u 
INNER JOIN (
    SELECT Name, ClientId, Count(*) AS ct FROM Contacts 
    GROUP BY Name, ClientId 
    HAVING COUNT(*) = 1 
) AS h 
ON u.Name = h.Name AND u.ClientId = h.ClientId 

さらにいくつかのクエリを合併することはそれは大したことではないのです必要とされるものである場合しかし、おそらくこれを処理するより良い方法があるようです。助言がありますか?

EDIT:サンプルデータ

クエリ後
Name  | Phone   | Email  | ClientId 
------------------------------------------------------ 
Person1 | NULL   | NULL   | 42 
Person1 | 555-555-5555 | [email protected] | 42 
Person2 | NULL   | NULL   | 21 
Person2 | NULL   | NULL   | 21 
Person3 | 555-555-5555 | NULL   | 79 
Person3 | NULL   | NULL   | 79 
Person4 | 555-555-5555 | NULL   | 49 
Person4 | NULL   | [email protected] | 49 
Person5 | 555-555-5555 | NULL   | 91 
Person5 | 555-555-5555 | [email protected] | 91 
Person6 | 555-555-5555 | NULL   | 91 

返されたデータセット -

Name  | Phone   | Email  | ClientId 
------------------------------------------------------ 
Person1 | 555-555-5555 | [email protected] | 42 
Person2 | NULL   | NULL   | 21 
Person3 | 555-555-5555 | NULL   | 79 
Person4 | 555-555-5555 | [email protected] | 49 
Person5 | 555-555-5555 | [email protected] | 91 
Person6 | 555-555-5555 | NULL   | 91 

Person4のためのデータのマージが理想的な状況であるが、必ずしも答え私は探していませんこのSOの質問のために。名前ORの電子メールが入力されているその状況では、データが失われていない限り、重複しても問題ありません。

+0

あなたは、いくつかの実際のデータを表示し、データ私は、実際のデータを表示することはできませんが、私はいくつかのアップ私を与えるあざけります – TheGameiswar

+0

@TheGameiswarを期待してくださいすることができ数分。 – JNYRanger

+0

それは役に立つだろう、私は実際のデータを書いたときのサンプルデータを意味した – TheGameiswar

答えて

2

..

select 
name,max(phone),max(email),clientid 
from 
Table t 
group by name,clientid 
+0

シンプルで、これまでに見つかったすべてのシナリオに対応しています。私はこの問題を過度に思っていることを知っていました。ありがとう! – JNYRanger

+0

@JNYRanger:私も – TheGameiswar

+0

:)しかし、なぜ 'max()'? – Serg

-1

は、特定の列に基づいて重複を選択するには、この

WITH CT AS(
      SELECT Name, Phone, Email, CompanyId, 
    --This part determines duplicates by field 
       RN = ROW_NUMBER()OVER(PARTITION BY Name,CompanyId ORDER BY Name) 
      FROM Contacts 
     ) 
     select FROM CT WHERE email <> '' and phone <> '' 

を試してみてくださいここ

ROW_NUMBER()OVER(PARTITION BY {column1}, {column2}..... 
2

これは、すべてのnameのために「最善」の行を返します。それを行います。最善の追加列数(Mail,Phone)はnullではありません。これは確かに動作します

select top(1) with ties * 
from Contact 
order by row_number() over (partition by Name order by 
     case when Phone is null then 0 else 1 end + case when Email is null then 0 else 1 end desc) 
+0

4行目をマージする必要があります.Person4 – TheGameiswar

+0

マージルールについてはわかりません。たとえば空文字列 'Skype'がもう1つあり、' Person4'行の値が 'abc'と' xyz'であるとします。どのSkypeがマージされた行にあるはずですか? – Serg

+0

@Sergこれは良い点ですが、これは決して起こりません。データに重複したレコードがあり、Email&Phoneの両方に(同じ値ではなく)値が設定されているシナリオはありません。それは何も持っていないもの、電子メールだけ、電話だけ、または完全に人口が多いもののいずれかである。それが唯一の電話または電子メールの場合は、両方の二重引用符が入力された場合、複製内に常に同じ値を持ちます。私は幸運にも、データが混乱しているが、操作するのはそれほど悪くない。 – JNYRanger

関連する問題