Tuesday 4 September 2018

The outer join does not indicate the desired lines (null)

I have a table which contains User IDs, Period IDs and Qty:

User Period Qty
---- ------ ---
   1  11201   3
   1  11202   2
   1  11203   5
   2  11202   4
   2  11203   1

Note: User 2 started in Period 11202 so he/she does not have a row for Period 11201
I need to get the Users only from the latest Period...
SELECT User FROM table WHERE Period = 11203

...and then use these User IDs on the same table to get Period 11201 and 11202 Qty for both users.
The problem: I need to see the (null) Qty for User 2 in Period 11201. Like so:
User Period    Qty
---- ------  -----
   1  11201      3
   1  11202      2
   2  11201 (null)
   2  11202      4

I can't figure out the query/joins to achieve it. So far I have this but predictably it gives me only 3 rows (User 1, Periods 11201/11202 and User 2, Period 11202):
SELECT a.User, a.Period, a.Qty
FROM (SELECT User FROM table WHERE Period = 11203) b
LEFT JOIN table a
ON b.User = a.User
WHERE a.Period BETWEEN 11201 AND 11202


You need to get all the required periods and make a Cartesian product of these with the Users first, and then outer join to that:
SELECT b.User, p.Period, a.Qty
FROM (SELECT User FROM table WHERE Period = 11203) b
CROSS JOIN (SELECT DISTINCT Period FROM table
            WHERE Period BETWEEN 11201 AND 11202) p
LEFT JOIN table a
ON a.User = b.User
AND a.Period = p.Period

Note also the SELECT needs to get the User and Period from the outer table not the inner one, otherwise everything will be null on the rows where the user is missing.

0 comments:

Post a Comment