使用NOT EXISTS过滤查询

时间:2014-09-10 17:30:47

标签: sql-server tsql not-exists

我目前正在尝试使用Visual Studio中的SQL Server查询数据库。有问题的数据库包含支付信息,主要通过OrderID和许可证ID识别交易及其产生的软件许可证。有时,这些许可证因滥用而被撤销。

现在,我正在尝试运行一个基于此的方式返回所有客户的查询:

Select 
   [Order].LastName,
   [Order].FirstName,
   [Order].CompanyOrganization,
   [Order].EmailAddress,
   [Order].Country,
   [License].LicenseID,
   [License].InstanceCount

From [Order], [License]

Where
    [License].OrderID = [Order].OrderID
    AND [Order].Status = 1
    AND not exists (Select LicenseID From [LicenseRevocation])

Order by [License].InstanceCount DESC;

查询没有返回任何结果,我知道这是因为“NOT EXISTS”部分。但是,我不确定为什么。有人可以清楚“EXISTS”如何工作以及如何在我的查询中实现它?

4 个答案:

答案 0 :(得分:4)

exists()函数如果其中的查询将产生至少一条记录,则为真,因此not exists()仅在其中的查询将产生零记录时才为真。

在您的情况下,您正在查询LicenseRevocation内的整个not exists(),因此只有在该表完全为空时,您的查询才会返回任何内容。

您可以在查询中使用条件来查找其中的特定记录,如下所示:

not exists (Select * From [LicenseRevocation] Where LicenseID = [License].LicenceID)

这将使查询返回LicenseRevocation表中没有相应记录的记录。

答案 1 :(得分:2)

如果存在或不存在,您需要定义检查值的条件

还为联接使用ON子句语法。

Select [Order].LastName
     , [Order].FirstName
     , [Order].CompanyOrganization
     , [Order].EmailAddress
     , [Order].Country
     , [License].LicenseID
     , [License].InstanceCount

From [Order] 
INNER JOIN [License] ON [License].OrderID = [Order].OrderID 

Where [Order].[Status] = 1 
AND NOT EXISTS (Select 1 
                From [LicenseRevocation]
                WHERE LicenseID = [License].LicenseID)  --<-- you are missing this condition
Order by [License].InstanceCount DESC;

答案 2 :(得分:0)

此解决方案使用NOT IN和正确的JOIN语法,但应该为您提供所需的结果

SELECT  [Order].LastName, [Order].FirstName, [Order].CompanyOrganization, 
        [Order].EmailAddress, [Order].Country,
        [License].LicenseID, [License].InstanceCount
FROM    [Order] 
INNER JOIN [License] ON [License].OrderID = [Order].OrderID 
WHERE  [Order].Status = 1 
AND  [License].LicenseID NOT IN  (
     SELECT  LicenseID
     FROM    [LicenseRevocation] )
ORDER BY [License].InstanceCount DESC;

PS。使用表ALIAS

答案 3 :(得分:0)

首先,使用正确的JOINS编写查询,并使用标准的LEFT OUTER JOIN:

Select 
   [Order].LastName,
   [Order].FirstName,
   [Order].CompanyOrganization,
   [Order].EmailAddress,
   [Order].Country,
   [License].LicenseID,
   [License].InstanceCount

From [Order]
INNER JOIN [License] ON [License].OrderID = [Order].OrderID
LEFT OUTER JOIN [LicenseRevocation] ON [License].LicenseID = [LicenseRevocation].LicenseID
Where [Order].Status = 1
AND [LicenseRevocation].LicenseID IS NULL

Order by [License].InstanceCount DESC;