Home > Net >  case expression inside this left join?
case expression inside this left join?

Time:01-18

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.

  • Related