如何创建一个查找无关联记录的SQL语句?

时间:2010-03-22 08:44:43

标签: inner-join exists sql

我有两张表如下:

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

上述语句解析正确但未提供我正在寻找的确切结果。有人可以帮忙吗?

4 个答案:

答案 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 keywordsee also

在SQL Server上,NOT EXISTS通常为thought to be more performant。在其他RDMS的your mileage may vary

答案 2 :(得分:1)

至少有两种方法可以找到无关联的记录。

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提到的那样表现不佳

2。使用NOT EXISTS

rohancragg和其他人建议使用NOT EXISTSIN的各种版本:

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 ...)