2013-05-08 43 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