SQL“Where Not Exists”不返回任何行

时间:2013-05-08 21:53:45

标签: sql sql-server

这是我想要完成的事情: 1.从users表中提取用户ID(documents.ownerID是Users.Handle的外键) 2.对于没有在过去90天内在文档表中创建的记录的用户

这是我到目前为止的查询(我通过SQL Studio Management 2012运行):

Select Users.UserID 
From Documents  
Inner Join Users on documents.OwnerID = users.handle
Where Not Exists
(
Select * 
From Documents
Where documents.creationtime >= Dateadd(day, -90, getutcdate())
)
Group by Users.UserID
Order by Users.UserID ASC

输出中没有返回任何内容。但是,当我从“不存在”语句中删除“不”时,我得到的用户输出具有在过去90天内在文档表中创建的记录。此外,如果我将“> =”指示符更改为“=”,我也会收到输出。我认为问题在于我对EXIST声明没有深刻理解。我非常感谢你的帮助。

5 个答案:

答案 0 :(得分:9)

原因是因为您的子查询没有相关性。因此,where子句说:创建时间大于90天的文档中不存在记录。有这样的记录,所以where子句总是失败。

我的猜测是你想要用户。如果是这样,那么试试这个where条款:

where not exists (select *
                  from documents d2
                  where d2.creationtime >= Dateadd(day, -90, getutcdate()) and
                        d2.OwnerId = users.handle
                 )

答案 1 :(得分:3)

一种方法是将Documents表放在子查询,将其从外部查询中删除,从而使子查询成为相关的:

SELECT Users.UserID 
FROM Users 
WHERE NOT EXISTS
    (
    SELECT * 
    FROM Documents
    WHERE Documents.OwnerID = Users.handle
      AND Documents.creationtime >= Dateadd(day, -90, getutcdate())
    ) ;

这样,你也可以免费摆脱GROUP BY

答案 2 :(得分:2)

在不使用子查询的情况下获得相同结果的快捷方式是使用左连接并在Documents表中检查NULL,如下所示:

SELECT Users.UserID
FROM Users  
LEFT JOIN Documents on documents.OwnerID = users.handle
    AND documents.creationtime >= Dateadd(day, -90, getutcdate())
WHERE Documents.OwnerID IS NULL
ORDER BY Users.UserID ASC

答案 3 :(得分:1)

如果NOT EXISTS中的查询返回任何行,则返回0行。你说的是“如果这个查询没有返回任何内容就给我回行”

编辑:是的,戈登在下面有正确的想法。如果此查询没有为此用户返回任何内容,您想说“为此用户提供行”

编辑2:以下是我的意思:)

答案 4 :(得分:0)

如果表格对于SQL Server的更高版本

而言不是太大,则另一种选择是使用“except”
  

SELECT Users.UserID FROM Documents INNER JOIN Users ON   documents.OwnerID = users.handle WHERE documents.creationtime> =   Dateadd(day, - 90,getutcdate())GROUP BY Users.UserID

     

除非

     

(SELECT * FROM Documents WHERE documents.creationtime> =   Dateadd(day, - 90,getutcdate()))ORDER BY Users.UserID ASC