在SQL Server 2008中,我有一个表,其中包含来自我们网站的下载活动的数据。我已经创建了一个工具来手动匹配Web下载表中的每个公司到我们客户数据库中的帐户。并非所有下载者都属于客户公司。这些非客户与默认帐户匹配。
下载表中的公司名称可能以多种不同的方式拼写,因此许多不同的名称与同一帐户匹配。
公司可能存在于不同的国家。每个公司都有自己的客户数据库中每个国家/地区的帐户,但只有一个默认帐户(每个国家/地区不是一个)。为了使这更加复杂,下载者不需要指定国家(无关)。在这些情况下,匹配是最可能的帐户。在这些情况下,country字段将包含一个空格。到目前为止,非常好。
当我想从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 :(得分: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
答案 1 :(得分: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
- 最好在子查询中执行distinct,然后从中选择TOP 15
,或者使用由两个值分区的排名函数。
答案 2 :(得分: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;
通过单独加入公司名称和国家/地区名称(而不是单个串联字符串),应该可以使用任何合适的现有索引。