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;

§。需要这部分来选择开放国家/地区字段的情况(请参阅上面的解释)。

有没有人可以帮助我创建更有效的选择?

4

3 回答 3

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
于 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;

我不相信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 回答