so I have this left join
LEFT JOIN LATERAL (SELECT d.country FROM db.patient_info d
WHERE d.id IN (SELECT DISTINCT st.category FROM db.surgery_types st, db.surgery_record sr
WHERE sr.id = st.surgery_record_id AND sr.surgery_type_id = m.id)
ORDER BY d.priority, d.country
LIMIT 1
) c ON TRUE
the issue is that sometimes d.country comes back null. How can I add a case statement in the left join so that when d.country IS NULL then 'USA'?
My results look like this
| Patient Name | Surgery Type |
|---|---|
| Dave | USA |
| Richard | EU |
| Ben | EU |
| Sally | JP |
| Bob | null |
| Dicky | null |
I want to modify the left join so that it looks more like this
| Patient Name | Surgery Type |
|---|---|
| Dave | USA |
| Richard | EU |
| Ben | EU |
| Sally | JP |
| Bob | USA |
| Dicky | USA |
Thoughts?
CodePudding user response:
Use coalesce which returns the first non-null value.
-- I have no idea if this lateral join is valid.
LEFT JOIN LATERAL (
SELECT coalesce(d.country, 'USA')
FROM db.patient_info d
WHERE d.id IN (
SELECT DISTINCT st.category
FROM db.surgery_types st, db.surgery_record sr
WHERE sr.id = st.surgery_record_id AND sr.surgery_type_id = m.id
)
ORDER BY d.priority, d.country
LIMIT 1
) c ON TRUE
Though the order by will still use null so it might not sort properly. You might want to split this into a CTE.
-- Again, no idea if the lateral join is valid,
-- just showing a technique.
with countries as(
SELECT coalesce(d.country, 'USA') as country
FROM db.patient_info d
WHERE d.id IN (
SELECT DISTINCT st.category
FROM db.surgery_types st
JOIN db.surgery_record sr ON sr.id = st.surgery_record_id
-- Don't know what m is
WHERE sr.surgery_type_id = m.id
)
)
with first_country as (
select country
from countries
order by priority, country
limit 1
)
select
...
LEFT JOIN LATERAL countries on true
Finally, it might be simpler and faster to update the table to set all null countries to USA, and then make the column not null.
CodePudding user response:
Not looking into your business logic and whether a lateral join is needed at all or a scalar subquery in the select list of expressions would be enough, here is my suggestion.
CROSS JOIN LATERAL
(
select coalesce
(
( /* your lateral subquery in the brackets here */),
'USA'
) as country
) as c
You do not need left join anymore. Please note that this will only work if the subquery is scalar.
