我有两张表如下:
tblCountry (countryID, countryCode)
tblProjectCountry(ProjectID, countryID)
tblCountry
表是包含其代码的所有国家/地区的列表,tblProjectCountry
表将某些国家/地区与某些项目相关联。我需要一个SQL语句,它给出了一个国家/地区代码列表,这些国家/地区代码在tblProjectCountry
表中没有相关记录。到目前为止,我到了这里:
SELECT tblCountry.countryID, tblCountry.countryCode
FROM tblProjectCountry INNER JOIN
tblCountry ON tblProjectCountry.countryID = tblCountry.countryID
WHERE (SELECT COUNT(ProjectID)
FROM tblProjectCountry
WHERE (ProjectID = 1) AND (countryID = tblCountry.countryID)) = 0
上述语句解析正确但未提供我正在寻找的确切结果。有人可以帮忙吗?
答案 0 :(得分:3)
这有用吗?
SELECT countryID, countryCode
FROM tblCountry
WHERE countryID NOT IN ( SELECT countryID FROM tblProjectCountry )
答案 1 :(得分:3)
另一种选择:
SELECT outerTbl.countryID, outerTbl.countryCode
FROM tblCountry AS outerTbl
WHERE NOT EXISTS
(
SELECT countryID FROM tblProjectCountry WHERE countryID = outerTbl.countryID
)
这使用了所谓的correlated subquery
请注意,我还使用the EXISTS keyword(see also)
在SQL Server上,NOT EXISTS通常为thought to be more performant。在其他RDMS的your mileage may vary。
答案 2 :(得分:1)
至少有两种方法可以找到无关联的记录。
LEFT JOIN
SELECT DISTINCT -- each country only once
tblCountry.countryID,
tblCountry.tblCountry
FROM
tblCountry
LEFT JOIN
tblProjectCountry
ON
tblProjectCountry.countryID = tblCountry.countryID
WHERE
tblProjectCountry.ProjectID IS NULL -- get only records with no pair in projects table
ORDER BY
tblCountry.countryID
正如erikkallen提到的那样表现不佳。
NOT EXISTS
rohancragg和其他人建议使用NOT EXISTS
或IN
的各种版本:
SELECT
tblCountry.countryID,
tblCountry.tblCountry
FROM
tblCountry
WHERE
-- get only records with no pair in projects table
NOT EXISTS (SELECT TOP 1 1 FROM tblProjectCountry WHERE tblProjectCountry.countryID = tblCountry.countryID)
ORDER BY
tblCountry.countryID
取决于您的DBMS以及国家和项目表的大小,这两个版本都可以表现得更好。
在我对MS SQL 2005的测试中,对于包含约250个国家/地区和~5000个项目的表的第一次和第二次查询之间没有显着差异。然而,在超过3M 项目的桌面第二个版本(使用NOT EXISTS
)表现更好,更好。
所以一如既往,检查这两个版本是值得的。
答案 3 :(得分:0)
SELECT ... WHERE ID NOT IN(SELECT ...)