简体   繁体   中英

How to join calendar table in order to get NULLs where there is no values in the main table?

Imagine I have a table for February with users and their COVID-19 quarantine isolation violations during a single day. If the user didn't violate isolation whole day there is no such row in the table for this date.

user date       violations
1    2020-02-01 2
1    2020-02-03 1
1    2020-02-15 2
3    2020-02-04 1
3    2020-02-24 3

What type of join should I use for my query in order to show every day in February for each user and violations column value (null or 0 if there is no such row):

user date       violations
1    2020-02-01 2
1    2020-02-02 NULL
1    2020-02-03 1
1    2020-02-04 NULL
...
1    2020-02-29 NULL
3    2020-02-01 NULL
3    2020-02-02 NULL
3    2020-02-03 NULL
3    2020-02-04 1
...
3    2020-02-29 NULL

I have a calendar table for February:

date
2020-02-01
2020-02-02
...
2020-02-29

I tried a full outer join, but it works as I expected only for one user.

Use a cross join to generate the rows and then left join to bring in the existing data:

select c.date, u.user, v.violations
from calendar c cross join
     (select distinct user from violations) u left join
     violations v
     on c.date = v.date and u.user = v.user

If you have a separate table for users, then use that instead of the subquery for u . After all, perhaps there are users who had no violations in February.

If you have a separate table of users, then you need a cross join of calendar and users, and then left outer join to the violations table, as Gordon Linoff has already shown.

However, if you don't have a table of users, and you must just pick them from the violations table, then you should use the partition outer join which exists exactly for this purpose:

select v.user, c.date, v.violations
from   calendar c left outer join violations v
       PARTITION BY (v.user)                      -- this is what you must add
       on c.date = v.date
order  by user,date
;

The benefit is that you don't have to read the violations table twice.

Note that DATE and USER and keywords and shouldn't be used as column names; I followed your lead with this, but your lead is not good.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM