2009-04-03 9 views
0

私はすでに質問Deleting duplicate records using a temporary tableをチェックアウトしてきた、それはかなりこの質問で私を支援するために十分行っていません。複数のフィールドを使用してテーブルから重複レコードを抽出するにはどうすればよいですか?

私はSQL 2000 Serverの上でホストされている約20万のアドレス位置のテーブルを持っています。このテーブルは、長年にわたり様々な関係者からの無効な入力によって引き起こされたテーブル内の重複データに大きな問題を抱えています。重複しているレコードのリストを出力して、それらを整理するための長いプロセスを開始する必要があります。

だから、次の表の構造を考える:私も道も大きく悪夢になるだろう、まだタイプミスやスペルのバリエーションを気にするつもりはありません最初の解析のために

Table Company( 
    CompanyId NVarChar(10) Not Null Constraint PK_Locations Primary Key, 
    CompanyName NVarChar(30), 
    CompanyAddress NVarChar(30), 
    CompanyCity NVarchar(30), 
    CompanyState Char(2), 
    CompanyZip NVarChar(10), 
    DateCreated DateTime, 
    LastModified DateTime, 
    LastModifiedUser NVarChar(64) 
) 

をそのIまだ解決についての最初の手がかりを得ていない。レコードが複数のレコードには、以下の条件に一致したときに、重複すると考えられているこの部分については、これ

(会社名またはCompanyAddress)とCompanyCityとCompanyState

ジップが除外されているので、理由場所の多くは郵便番号が紛失しています。多くの場所が誤って入力されています。

都市内の単一の住所に複数の企業が合法的に存在する可能性があることは、単一の市町村内の企業[正直言ってマクドナルドなど]そして州(例えば、ショッピングモールやオフィスビルの中)であるが、今のところ、これらは少なくともあるレベルの人間の注意を保証し、それらを報告書に含めると考える。

1つのフィールドの一致はケーキですが、複数のフィールドにアクセスしたときには、特に条件付きのフィールドがある場合は元に戻ります。

答えて

2
WITH q AS (
      SELECT Company.*, 
       ROW_NUMBER() OVER (PARTITION BY CompanyState, CompanyCity, CompanyName ORDER BY CompanyID) AS rnName, 
       ROW_NUMBER() OVER (PARTITION BY CompanyState, CompanyCity, CompanyAddress ORDER BY CompanyID) AS rnAddress 
      FROM Company 
     ) 
SELECT * 
WHERE  rnName > 1 OR rnAddress > 1 

注意、しかし、そのデータは次のようになります場合:

CompanyID CompanyName CompanyAddress 
--------- ----------- -------------- 
1   McDonalds Avenue 1 
2   McDonalds Avenue 2 
3   Starbucks Avenue 2 

が、その後、両方のレコード 23が削除されます(あなたが要求するものであるが、おそらくないあなたが何を望みますか)その後、

あなただけの重複を持つすべての行を一覧表示したい場合は、問題:

SELECT * 
FROM Company co 
WHERE EXISTS 
     (
     SELECT 1 
     FROM Company cn 
     WHERE cn.CompanyState = co.CompanyState 
       AND cn.CompanyCity = co.CompanyCity 
       AND cn.CompanyName = co.CompanyName 
       AND cn.CompanyID <> co.CompanyID 
     ) 
     OR EXISTS 
     (
     SELECT 1 
     FROM Company ca 
     WHERE ca.CompanyState = co.CompanyState 
       AND ca.CompanyCity = co.CompanyCity 
       AND ca.CompanyAddress = co.CompanyAddress 
       AND ca.CompanyID <> co.CompanyID 
     ) 

これはSQL Server 2000でも動作します。

(CompanyState, CompanyCity, CompanyName)(CompanyState, CompanyCity, CompanyAddress)にインデックスを付けると、このクエリが大幅に改善されます。

+0

リストされたすべての複製が必要です。削除キューにまっすぐに置かれないので、すべての複製がリストされています。すべての複製が削除される前に、複製から複製までの請求書をマスタレコードにマージする必要があります。 – BenAlabaster

+0

これはSQL 2000 Serverで動作しますか?それは私に次のエラーを与えます: メッセージ156、レベル15、状態1、行1 キーワード 'WITH'の近くの構文が正しくありません。 メッセージ195、レベル15、状態10、行3 'ROW_NUMBER'は認識された関数名ではありません。 – BenAlabaster

+0

いいえ、これはSQL Server 2000では機能しません – Quassnoi

0
SELECT 
    C1.CompanyID, 
    C2.CompanyID 
FROM 
    Company C1 
INNER JOIN Company C2 ON 
    (C2.CompanyName = C1.CompanyName OR C2.CompanyAddress = C1.CompanyAddress) AND 
    C2.CompanyCity = C1.CompanyCity AND 
    C2.CompanyState = C2.CompanyState AND 
    C2.CompanyID > C1.CompanyID 

3つ以上の一致がある場合、それらはリストに複数回表示されます。クエリーから正確に返ってきたいものに応じて、それを処理するさまざまな方法があります。

さらに、フロントエンドコーディングを検討して、システムへのアドレスの取得方法とユーザートレーニングの方法を制限することを強くお勧めします。

+0

Hehe、はい、私はより良いフロントエンドコーディングを支援するために雇われました。私の到着前に起こっている5年間の騒乱の清掃の過程でも。 – BenAlabaster

+0

大丈夫、重複の単一のインスタンスだけを取り戻すための提案はありますか?私はカーソルでそれらを解析することができると思うが、それを行うクエリベースの方法はありますか? – BenAlabaster

+0

あなたは単一のインスタンスとして何を定義し、何を見たいでしょうか?たとえば、住所、市区町村のAと一致する名前、都市、州、会社Cに一致するA社とB社がある場合は、それをどのように見たいと思いますか? –

0

はこれが重複しているものをお見せなければならない

Select field1, field2, ... etc, count(*) 
FROM Company, 
GROUP BY field1, field2, ... 
HAVING count(*) > 1 

...このような何かを試してみてください。

+0

+1これは私が与えるつもりの答えです。 –

+0

(CompanyName OR CompanyAddress)に重複がどのように表示されますか? – Quassnoi

+0

しかし、* OR *状況は考慮されません。グループ内のすべてのフィールドが一致する場合にのみアカウントになります。 – BenAlabaster

関連する問題