2013-05-08 10 views
5

Oto, co próbuję osiągnąć: 1. Wyciągnij ID użytkownika z tabeli użytkowników (documents.ownerID jest obcym kluczem Users.Handle) 2. Dla użytkowników którzy nie mają rekordu, który został utworzony w tabeli dokumenty w ciągu ostatnich 90 dniSQL "Where Not Exists" nie zwraca żadnych wierszy

Oto zapytanie, że mam tak daleko (używam tego poprzez SQL Management Studio 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 

Nic nie jest zwracane na wyjściu. Jednak po usunięciu "Not" z instrukcji "Not Exists" otrzymuję dane wyjściowe użytkowników, którzy mają rekord utworzony w tabeli dokumentów w ciągu ostatnich 90 dni. Ponadto, jeśli zmienię wskaźnik "> =" na "=", również otrzymam dane wyjściowe. Myślę, że problem polega na tym, że nie mam pełnego zrozumienia stwierdzenia EXIST. Bardzo doceniam twoją pomoc.

Odpowiedz

1

Jeśli zapytanie w NOT EXISTS zwraca DOWOLNE wiersze, otrzymasz 0 wierszy do tyłu. Mówisz "oddaj mi wiersze, jeśli zapytanie to nic nie zwraca"

EDYCJA: I tak, Gordon ma właściwy pomysł poniżej. Chcesz powiedzieć „daj mi wiersze dla tego użytkownika, jeśli ta kwerenda zwraca nic dla tego użytkownika”

EDIT 2: poniżej i powyżej mi chodziło :)

+0

Moje rozumienie „nie istnieje” jest to, że to zapytanie zwróci wszystko, co nie jest zawarte w pod-zapytaniu, czy to prawda? Tak więc, jeśli użytkownik nie miałby utworzonego rekordu w ciągu 90 dni, to zostałby on zwrócony w moim konkretnym zapytaniu (po wprowadzeniu zmian przez Gordona lub kurs), prawda? Dzięki za pomoc. – user2124571

+0

Tak, zazwyczaj chcesz połączyć podkwerendę NOT EXISTS z głównym zapytaniem. Tak więc w oryginale mówiliście: "zdobądźcie mi rekordy, jeśli nie ma wiersza w dokumentach z ostatnich 90 dni". W Gordon's, on mówi, "weź mi wszystkie rekordy, których użytkownik nie ma pokrewnego dokumentu z ostatnich 90 dni". Mam nadzieję, że to pomogło. – Aushin

+0

To absolutnie pomogło, dziękuję !! – user2124571

8

Powodem jest to, ponieważ nie jest podzapytanie skorelowane. Tak więc, klauzula where mówi: gdzie nie ma zapisów w dokumentach z czasem utworzenia dłuższym niż 90 dni. Są takie zapisy, więc klauzula where zawsze kończy się niepowodzeniem.

Domyślam się, że chcesz tego przez użytkownika. Jeśli tak, to spróbuj tego where klauzuli:

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

Instrukcja "EXISTS" jest jedną z tych interesujących, w których może odnosić się do zestawów danych poza nawiasami. Jest to dozwolone z tego samego powodu, że można go powiązać z innym zbiorem danych. –

+0

To działało dla mnie, dziękuję bardzo! – user2124571

3

Jednym ze sposobów jest umieszczenie tabeli Documents wewnątrz podzapytania tylko, usuwając go z zapytania zewnętrznego, tak czyniąc podzapytanie skorelowane One:

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

W ten sposób można również pozbyć się GROUP BY za darmo.

2

Skrót, aby uzyskać takie same wyniki bez użycia sub-maila byłoby użyć LEFT JOIN i sprawdzić NULL w tabeli dokumenty tak:

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 
Powiązane problemy