Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL "Where Not Exists" is not returning any rows

Tags:

sql

sql-server

Here is what I am trying to accomplish: 1. Pull user ID from the users table (documents.ownerID is foreign key of Users.Handle) 2. For users who do NOT have a record that was created in the documents table within the last 90 days

Here is the query that I have so far (I am running this through 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

Nothing is returned in the output. However, when I remove the "Not" from the "Not Exists" statement I get an output of users who have a record that was created in the documents table within the last 90 days. Also, if I change the ">=" indicator to "=" I receive output as well. I think the problem is that I don't have a firm understanding of the EXIST statement. I greatly appreciate your help.

like image 953
user2124571 Avatar asked May 08 '13 21:05

user2124571


People also ask

WHERE not exists in SQL query?

NOT EXISTS is used with a subquery in the WHERE clause to check if the result of the subquery returns TRUE or FALSE. The Boolean value is then used to narrow down the rows from the outer select statement.

How do you check if record not exists in SQL?

The EXISTS operator is used to test for the existence of any record in a subquery. The EXISTS operator returns TRUE if the subquery returns one or more records.

What to use instead of not exists in SQL?

An alternative for IN and EXISTS is an INNER JOIN, while a LEFT OUTER JOIN with a WHERE clause checking for NULL values can be used as an alternative for NOT IN and NOT EXISTS.

What does not exist mean in SQL?

NOT EXISTS means nothing returned by sub query. EXISTS as opposite means "one or more rows returned by subquery" SELECT * FROM Users as Homeless WHERE NOT EXISTS (SELECT * FROM Addresses WHERE Addresses.userId = Users.userId)


2 Answers

The reason is because your subquery is not correlated. So, the where clause is saying: where no record exists in documents with a creation time greater than 90 days. There are such records, so the where clause always fails.

My guess is that you want this by user. If so, then try this where clause:

where not exists (select *
                  from documents d2
                  where d2.creationtime >= Dateadd(day, -90, getutcdate()) and
                        d2.OwnerId = users.handle
                 )
like image 66
Gordon Linoff Avatar answered Sep 20 '22 22:09

Gordon Linoff


One way is to put the Documents table inside the subquery only, removing it from the external query, so making the subquery a correlated one:

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

This way, you can also get rid of the GROUP BY for free.

like image 34
ypercubeᵀᴹ Avatar answered Sep 21 '22 22:09

ypercubeᵀᴹ