I have the following table:
org_id | person_id | month | consultation_mode | professional_domain | number_consultations 1 | 1 | 01-03-2018 | in person | doctor | 3 1 | 1 | 01-03-2018 | telephone | doctor | 2 1 | 1 | 01-03-2018 | telephone | nurse | 1 2 | 4 | 01-01-2015 | telephone | doctor | 2 2 | 4 | 01-01-2015 | home visit | other | 4 2 | 4 | 01-12-2021 | null | null | null
I would like to have for each org_id, person_id, month a line for each category of consultation_mode and professional_domain, as per the below:
org_id | person_id | month | consultation_mode | professional_domain | number_consultations 1 | 1 | 01-03-2018 | in person | doctor | 3 1 | 1 | 01-03-2018 | in person | nurse | 0 1 | 1 | 01-03-2018 | in person | other | 0 1 | 1 | 01-03-2018 | telephone | doctor | 2 1 | 1 | 01-03-2018 | telephone | nurse | 1 1 | 1 | 01-03-2018 | telephone | other | 0 1 | 1 | 01-03-2018 | home visit | doctor | 0 1 | 1 | 01-03-2018 | home visit | nurse | 0 1 | 1 | 01-03-2018 | home visit | other | 0 2 | 4 | 01-01-2015 | in person | doctor | 0 2 | 4 | 01-01-2015 | in person | nurse | 0 2 | 4 | 01-01-2015 | in person | other | 0 2 | 4 | 01-01-2015 | telephone | doctor | 2 2 | 4 | 01-01-2015 | telephone | nurse | 0 2 | 4 | 01-01-2015 | telephone | other | 0 2 | 4 | 01-01-2015 | home visit | doctor | 0 2 | 4 | 01-01-2015 | home visit | nurse | 0 2 | 4 | 01-01-2015 | home visit | other | 4 2 | 4 | 01-12-2021 | in person | doctor | 0 2 | 4 | 01-12-2021 | in person | nurse | 0 2 | 4 | 01-12-2021 | in person | other | 0 2 | 4 | 01-12-2021 | telephone | doctor | 0 2 | 4 | 01-12-2021 | telephone | nurse | 0 2 | 4 | 01-12-2021 | telephone | other | 0 2 | 4 | 01-12-2021 | home visit | doctor | 0 2 | 4 | 01-12-2021 | home visit | nurse | 0 2 | 4 | 01-12-2021 | home visit | other | 0
There are 3 consultation_mode: in person, telephone, home visit
& 3 professional_domain: doctor, nurse, other. How can I do this in SQL?
Advertisement
Answer
First, you will need a small table or CTE containing the full set of consultation_mode + professional_domain combinations, then you will use a CROSS JOIN (i.e. a Cartesian product) between this table and the unique set of (org_id, person_id, month), then you will LEFT JOIN your starting table to that.
Something like this:
table raw_data:
org_id | person_id | month | consultation_mode | professional_domain | number_consultations 1 | 1 | 01-03-2018 | in person | doctor | 3 1 | 1 | 01-03-2018 | telephone | doctor | 2 1 | 1 | 01-03-2018 | telephone | nurse | 1 2 | 4 | 01-01-2015 | telephone | doctor | 2 2 | 4 | 01-01-2015 | home visit | other | 4 2 | 4 | 01-12-2021 | null | null | null
table mode_domain:
consultation_mode | professional_domain in person | doctor in person | nurse in person | other telephone | doctor telephone | nurse telephone | other home visit | doctor home visit | nurse home visit | other
query:
select
base.org_id,
base.person_id,
base.month,
mode_domain.consulation_mode,
mode_domain.profesional_domain,
coalesce(raw_data.number_consulations, 0) as number_consulations
from
(select distinct org_id, person_id, month from raw_data) as base
cross join
mode_domain
left join
raw_data on raw_data.org_id = base.org_id
and raw_data.person_id = base.person_id
and raw_data.month = base.month
and raw_data.consulation_mode = mode_domain.consultation_mode
and raw_data.professional_domain = mode_domain.professional_domain
/