I'm trying to construct a query that will include a column indicating whether or not a user has downloaded a document. I have a table called HasDownloaded with the following columns: id, documentID, memberID. Finding out whether a user has downloaded a specific document is easy; but I need to generate a query where the results will look like this:
name id ---------------------- abc NULL bbb 2 ccc 53 ddd NULL eee 13
The ID isn't really important; what I'm interested in is whether the document has been downloaded (is it NULL or not).
Here is my query:
SELECT Documents.name, HasDownloaded.id FROM Documents LEFT JOIN HasDownloaded ON HasDownloaded.documentID = Documents.id WHERE HasDownloaded.memberID = @memberID
The problem is, this will only return values if an entry exists for the specified user in the HasDownloaded table. I'd like to keep this simple and only have entries in HasDownloaded for documents that have been downloaded. So if user 1 has downloaded abc, bbb, and ccc, I still want ddd and eee to show up in the resulting table, just with the id as NULL. But the WHERE clause only gives me values for which entries exists.
I'm not much of a SQL expert - is there an operator that will give me what I want here? Should I be taking a different approach? Or is this impossible?
However, moving the WHERE condition to the ON clause applies it to the individual tables prior to joining. This enables the left join to retain rows from the left table even though some column entries of those rows (entries from the right tables) do not satisfy the WHERE condition.
To use the WHERE clause to perform the same join as you perform using the INNER JOIN syntax, enter both the join condition and the additional selection condition in the WHERE clause. The tables to be joined are listed in the FROM clause, separated by commas. This query returns the same output as the previous example.
Is there a difference between the WHERE and ON clause? Yes. ON should be used to define the join condition and WHERE should be used to filter the data.
When doing a left join in SQL any filtering of the table after the join will turn it into an inner join. However there are some easy ways to do the filtering first. Suppose you've got some tables related to a website. The pages table describes the different pages on the site.
Move the condition in the WHERE clause to the join condition.
SELECT Documents.name, HasDownloaded.id FROM Documents LEFT JOIN HasDownloaded ON HasDownloaded.documentID = Documents.id AND HasDownloaded.memberID = @memberID
This is necessary whenever you want to refer to a left join-ed table in what would otherwise be the WHERE clause.
WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId
would be the normal way to do that. Some would shorten it to:
WHERE COALESCE(HasDownloaded.memberId, @memberId) = @memberId
You can, as Matt B. shows, do it in your JOIN condition - but I think that's much more likely to confuse folks. If you don't understand WHY moving it to the JOIN clause works, then I'd strongly suggest staying away from it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With