Sql server 筛选不存在的查询

Sql server 筛选不存在的查询,sql-server,tsql,not-exists,Sql Server,Tsql,Not Exists,我目前正试图在Visual Studio中使用SQL Server查询数据库。所涉及的数据库包含支付信息,主要通过OrderID和许可证ID识别交易及其产生的软件许可证。通常,这些许可证会因误用而被吊销 现在,我正在尝试运行一个查询,该查询将根据以下内容返回所有客户: Select [Order].LastName, [Order].FirstName, [Order].CompanyOrganization, [Order].EmailAddress, [Ord

我目前正试图在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;
查询没有返回任何结果,我知道这是因为不存在部分。然而,我不知道为什么。有人能弄清楚EXISTS是如何工作的,以及如何在我的查询中实现它吗?

此解决方案使用的是NOT IN和正确的连接语法,但应该会给出您想要的结果

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.使用表别名

您需要定义一个条件,在该条件下检查是否存在值

对联接也使用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;
如果函数中的查询将生成至少一条记录,则exists函数为true;因此,只有当函数中的查询将生成零条记录时,notexists函数才为true

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

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

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

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

首先,使用正确的联接编写查询,并使用标准的左外联接:

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;

从技术上讲,OP中的连接语法是正确的。但是,它是较旧的ANSI-89样式连接,而您的是较新的ANSI-92样式连接。92样式的连接更容易阅读,也不容易出错。@SeanLange谢谢Sean,这就是我的意思。更常见、更易于阅读和+1000,用于建议使用别名。还有一点可能是,不使用保留字作为对象名,因为使用它很痛苦。从技术上讲,OP的连接语法是正确的。但是,它是较旧的ANSI-89样式连接,而您的是较新的ANSI-92样式连接。92样式联接更易于阅读,也不太容易出错。另外,您的查询也不完全相同。如果LicenseRevocation中匹配的行数超过1行,则返回的行数将更多。非常感谢您对ANSI-89和ANSI-92的评论。关于LEFT JOIN to LicenseRevocation,我同意,只是我们过滤掉了任何匹配的记录,所以在这种情况下,最终结果是正确的。如果我们没有WHERE[LicenseRevocation].LicenseID为空,那么我完全同意你的看法。它可以工作!你能解释一下为什么我要选择1而不是某一列吗?这是我唯一不明白的部分。从逻辑上讲,如果它根据WHERE子句中定义的条件找到一行,则它选择1 True,否则返回NULL False,则没有区别。当您需要的是true或false时,我看不出尝试返回列值的意义,这可能比简单地选择1更昂贵。这非常有意义。谢谢