0

SQL Server 2008 には、Web サイトでのダウンロード アクティビティのデータを含むテーブルがあります。Web ダウンロード テーブルから顧客データベースのアカウントに各企業を手動で照合するためのツールを作成しました。すべてのダウンローダーが実際に顧客企業に属しているわけではありません。これらの非顧客は、既定のアカウントに一致します。

ダウンロード テーブルの会社名はさまざまな方法で綴られている可能性があるため、多くの異なる名前が同じアカウントに一致します。

企業はさまざまな国に存在する場合があります。各企業は、顧客データベース内の国ごとに独自のアカウントを持っていますが、既定のアカウントは 1 つだけです (国ごとに 1 つではありません)。これをさらに複雑にするために、ダウンローダーは国を指定する必要はありません (それについては何もしません)。そのような場合、マッチングは最も可能性の高いアカウントに対して行われます。この場合、国フィールドには空白が含まれます。ここまでは順調ですね。

問題は、webDownloadTable から、既存のアカウント (または既定のアカウント) と一致しない企業を一覧表示する場合に発生します。つまり、accountMatchingTable に存在しません。

webDownloadTable の最も重要な列は次のとおりです。

webDownloadTable(
ID int not null
webCompanyName varchar(200), 
webCountryName varchar(200), 
item integer(8),
......,
...
);

主キーはID.

マッチング テーブルは次のようになります。

accountMatchingTable(
AccountID int(8),
matchedCompanyName varchar(200),
matchedCountryName varchar(200),
......,
...
);

主キーは(AccountID, matchedCompanyName, matchedCountryName).

テーブルは適切に索引付けされているようです。

実際に機能する SQL 選択を作成しましたが、行数が増えると非常に遅くなります。会社名 + 国が一致しない上位 15 行を選択します。

SELECT  DISTINCT TOP 15 webCompanyName, webCountryName
FROM    webDownloadTable
WHERE   (webCompanyName + webCountryName NOT IN
        (SELECT matchedCompanyName + matchedCountryName FROM accountMatchingTable)  /*The combination of name and country from the matching table*/
)
    AND
    (webCompanyName + ' ' NOT IN
        (SELECT matchedCompanyName + matchedCountryName FROM accountMatchingTable)  /*The combination of name and an empty space from the matching table (see §. below)*/
    )
ORDER BY webCompanyName, webCountryName;

§。国フィールドが開いているケースを選択するには、この部分が必要です (上記の説明を参照)。

より効率的な選択の作成を手伝ってくれる人はいますか?

4

3 に答える 3

3

次のように 2 つのサブクエリを削除してはどうでしょうか。

SELECT  DISTINCT TOP 15 a.webCompanyName, a.webCountryName
FROM    webDownloadTable a
  LEFT OUTER JOIN accountMatchingTable b
    ON a.webCompanyName + a.webCountryName = b.webCompanyName + b.webCountryName
    OR a.webCompanyName + ' ' = b.webCompanyName + b.webCountryName
WHERE b.webCompanyName IS NULL
ORDER BY webCompanyName, webCountryName
于 2013-03-13T09:05:21.217 に答える
1

私はこれがトリックを行うと思います:

SELECT DISTINCT TOP 15 webCompanyName,
                       webCountryName
FROM   webDownloadTable
       LEFT OUTER JOIN accountMatchingTable
         ON webDownloadTable.webCompanyName = accountMatchingTable.matchedCompanyName
            AND (webDownloadTable.webCountryName = accountMatchingTable.matchedCountryName
                  OR accountMatchingTable.matchedCountryName = ' ')
WHERE  accountMatchingTable.matchedCompanyName IS NULL
ORDER  BY webCompanyName,
          webCountryName;

しかし、私は確信していません-サブクエリで区別を行い、それから選択するか、2つの値で分割するランキング関数を使用するDISTINCT TOP 15方が良いかもしれません。TOP 15

于 2013-03-13T09:08:09.107 に答える
1

NOT EXISTS次のように句を使用してみることができます。

SELECT  DISTINCT TOP 15 webCompanyName, webCountryName
FROM    webDownloadTable d
WHERE NOT EXISTS
(SELECT 1
 FROM accountMatchingTable m
 WHERE m.matchedCompanyName = d.webCompanyName AND
       m.matchedCountryName in (d.webCountryName, ' ')
)
ORDER BY webCompanyName, webCountryName;

会社名と国名を(単一の連結された文字列としてではなく)別々に結合することにより、適切な既存のインデックスを利用できるようになります。

于 2013-03-13T09:13:33.223 に答える