Reputation: 3829
I need to Join 3 tables in SQL Server. Those 3 tables have basically this schema:
Users Items UsersItems
+--------+ +--------+-------------+ +--------+--------+-------+
| UserID | | ItemID | Description | | UserID | ItemId | Value |
+--------+ +--------+-------------+ +--------+--------+-------+
| 1 | | 1 | desc1 | | 1 | 1 | 1 |
| 2 | | 2 | desc2 | | 1 | 2 | 2 |
| ... | | ... | desc3 | | 2 | 2 | 1 |
| n | | n | desc4 | | n | 1 | 1 |
+--------+ +--------+-------------+ +--------+--------+-------+
As you can see both Users and Items can grow indefinitely and UsersItems is used to express the relation between those two, also including a Value column.
I need a query to retrieve all users, and for each user I need all the items with it's corresponding Value.
If the relation doesn't exist in UsersItems
then Null (or a default value) should be returned for that row's Value
column.
The expected query result should be:
ResultSet
+--------+--------+-------+
| UserID | ItemID | Value |
+--------+--------+-------+
| 1 | 1 | 1 |
| 1 | 2 | 2 |
| 1 | n | NULL |
| 2 | 1 | NULL |
| 2 | 2 | 1 |
| 2 | n | NULL |
| n | 1 | 1 |
| n | n | NULL |
+--------+--------+-------+
Upvotes: 1
Views: 116
Reputation: 5346
Okay, since there are several answers that I think aren't correct, I'll post what I think the answer is:
SELECT Users.UserID,
Items.Description,
UsersItems.Value
FROM
Users
CROSS JOIN
Items
LEFT JOIN
UsersItems
ON
Users.UserID = UsersItems.UserID
AND
Items.ItemID = UsersItems.ItemID
I'm inferring from your comment about nulls that you want to see all Items againsts all Users, with the Value from the UsersItems table where it exists.
Upvotes: 2
Reputation: 66687
You do it like this:
SELECT Users.UserID, Items.Description, Items.Value
FROM Users
LEFT OUTER JOIN UsersItems ON Users.UserID = UsersItems.UserID
LEFT OUTER JOIN Items ON UserItems.ItemID = Items.ItemID
For more info on left outer join read the following:
The result of a left outer join (or simply left join) for table A and B always contains all records of the "left" table (A), even if the join-condition does not find any matching record in the "right" table (B). This means that if the ON clause matches 0 (zero) records in B, the join will still return a row in the result—but with NULL in each column from B. This means that a left outer join returns all the values from the left table, plus matched values from the right table (or NULL in case of no matching join predicate). If the right table returns one row and the left table returns more than one matching row for it, the values in the right table will be repeated for each distinct row on the left table. From Oracle 9i onwards the LEFT OUTER JOIN statement can be used as well as (+).
Upvotes: 0
Reputation: 4146
SELECT
Users.UserID,
Items.Description,
Items.Value
FROM Users LEFT OUTER JOIN UsersItems
ON Users.UserID = UsersItems.UserID
LEFT OUTER JOIN Items
ON UserItems.ItemID = Items.ItemID
Upvotes: 1