这是我想要完成的事情: 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声明没有深刻理解。我非常感谢你的帮助。
答案 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