2013-05-08 47 views
5

以下是我正在尝试完成的操作: 1.从users表中提取用户标识(documents.ownerID是Users.Handle的外键) 2.对于用户谁没有那是在文件表中的最近90天SQL“Where Exists”不返回任何行

这里创造了一个纪录是我迄今为止查询(我通过SQL工作室管理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声明没有一个明确的理解。我非常感谢你的帮助。

回答

1

如果NOT EXISTS中的查询返回ANY行,您将返回0行。你在说“如果这个查询什么都不返回,给我返回行”

编辑:是的,戈登有正确的想法下面。你想说“给我行此用户如果该查询返回任何该用户”

编辑2:通过下面我的意思:)

+0

我的理解,“不存在”的是,它的查询将返回不包含在子查询中的所有内容,对吗?因此,如果用户在90天内没有创建记录,那么他们会在我的具体查询中返回(在Gordon或者课程的编辑之后),对吧?谢谢你的帮助。 – user2124571 2013-05-08 22:44:10

+0

是的,你通常要将NOT EXISTS子查询连接到你的主要查询。所以在你的原始文件中,你是在说:“如果在过去90天的文件中没有任何一行,请给我记录。”在戈登的作品中,他说:“把我过去90天没有相关文档的所有记录都寄给我”。希望这有助于。 – Aushin 2013-05-08 22:54:21

+0

它绝对有帮助,谢谢! – user2124571 2013-05-08 22:55:04

8

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

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

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

“EXISTS”语句是一个有趣的语句,它可以实际引用括号外的数据集。允许将其与其他数据集相关联的原因。 – 2013-05-08 22:10:24

+0

这对我很有用,非常感谢! – user2124571 2013-05-08 22:22:37

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

的快捷方式将得到相同的结果,而无需使用一个子查询将在文件表使用左连接,并检查是否为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