2013-03-13 61 views
0

在SQL Server 2008中,我有一個表格,其中包含來自我們網站下載活動的數據。我製作了一個工具,可以將每個公司從Web下載表中手動匹配到我們的客戶數據庫中的帳戶。並非所有下載者實際上都屬於客戶公司。這些非客戶與默認帳戶相匹配。更高效的選擇

下載表中的公司名稱可能以許多不同的方式拼寫,因此許多不同的名稱會與相同的帳戶匹配。

公司可能存在於不同的國家。每個公司在客戶數據庫中都有自己的賬戶,但每個國家只有一個默認賬戶(不是每個國家/地區)。爲了使這更加複雜,下載者不需要指定國家(對此無關)。在這些情況下,將匹配到最可能的賬戶。在這種情況下,國家領域將包含一個空白空間。到現在爲止還挺好。

問題出現在我想列出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; 

§。需要這一部分來挑選那些國家領域開放的案例(見上面的解釋)。

有沒有人可以幫助我創建更高效​​的選擇?

+0

「表格似乎被很好的索引。」 accountMatchingTable上有哪些其他索引? (目前,看起來好像現有查詢不能在此表上使用任何索引。) – 2013-03-13 09:06:12

+0

select中使用的字段也被索引。 – 2013-03-13 10:34:43

回答

3

如何通過移除兩個子查詢,像這樣:

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 
+0

同意,做一個LEFT JOIN,然後查找NULL比應用於每一行試圖的子選擇效率高得多 – DRapp 2013-03-13 09:10:00

+0

@DaveSexton - 你錯過了'ORDER BY'子句 - 沒有它,'TOP 15'沒有意義。 – Bridge 2013-03-13 09:10:54

+0

@Bridge - 添加了ORDER BY – 2013-03-13 09:24:09

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; 

我不相信有關DISTINCT TOP 15雖然 - 它可能是最好在子查詢中完成不同的處理,然後從中選擇TOP 15,或者使用由您的兩個值進行分區的排名函數。

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; 

通過(作爲一個單一的,連接字符串代替)加盟的公司名稱和國家名稱分別,它應該是可能的利用任何合適的現有指標。

+0

+1 - 我也加入了個人專欄。羞於接受的答案不包括:-( – Bridge 2013-03-13 10:42:35