Home > Mobile >  Join condition do not show Nulls for a field
Join condition do not show Nulls for a field

Time:02-10

Let's say I have these two tables. The students table stores data about the student showing up to the respected class on a specific date. On the contrary, the classes table shows when the respected class started and when was the class last held.

How can I achieve this in postgreSQL 11.

select * from students

student_name          student_showed           class_name    
  Jeter                 2022-02-05                Math       
  Jeter                 2022-02-06                Math
  Jeter                 2022-02-07                Math
  Jeter                 2022-02-08                Math
  Jeter                 2022-02-09                Math
  Jeter                 2022-02-05                English
  Jeter                 2022-02-06                English
  Jeter                 2022-02-07                English
  Jeter                 2022-02-08                English
  Jeter                 2022-02-09                English
  Soriano               2022-02-05                Math
  Soriano               2022-02-06                Math
  Soriano               2022-02-07                Math
  Soriano               2022-02-08                Math
  Soriano               2022-02-09                Math
  Soriano               2022-02-05                English
  Soriano               2022-02-06                English
  Soriano               2022-02-07                English
  Soriano               2022-02-08                English
  Soriano               2022-02-09                English

Now for the classes table!

select * from classes

 class_name             class_started             class_held_date
   Math                   2022-02-05                2022-02-06
  English                 2022-02-05                2022-02-06
   Math                   2022-02-05                2022-02-07
  English                 2022-02-05                2022-02-07
   Math                   2022-02-05                2022-02-09
  English                 2022-02-05                2022-02-09

When I do a left-join on the two tables:

select s.*,c.class_started,c.class_held_date from students as s
left join classes as c on s.class_name = c.class_name and s.student_showed = c.class_held_date

student_name      student_showed      class_name     class_started     class_held_date  
  Jeter             2022-02-05          Math       
  Jeter             2022-02-06          Math           2022-02-05        2022-02-06
  Jeter             2022-02-07          Math           2022-02-05        2022-02-07
  Jeter             2022-02-08          Math
  Jeter             2022-02-09          Math           2022-02-05        2022-02-09
  Jeter             2022-02-05          English
  Jeter             2022-02-06          English        2022-02-05        2022-02-06
  Jeter             2022-02-07          English        2022-02-05        2022-02-07
  Jeter             2022-02-08          English
  Jeter             2022-02-09          English        2022-02-05        2022-02-09
  Soriano           2022-02-05          Math
  Soriano           2022-02-06          Math           2022-02-05        2022-02-06
  Soriano           2022-02-07          Math           2022-02-05        2022-02-07
  Soriano           2022-02-08          Math
  Soriano           2022-02-09          Math           2022-02-05        2022-02-09
  Soriano           2022-02-05          English
  Soriano           2022-02-06          English        2022-02-05        2022-02-06
  Soriano           2022-02-07          English        2022-02-05        2022-02-07
  Soriano           2022-02-08          English
  Soriano           2022-02-09          English        2022-02-05        2022-02-09

Since class_started in the classes tables is a static field, I want it to always show the value rather than show NULLS. I need to show a left join since the student should get credit for showing up to the classes regardless if the classes were held or not.

Can someone please provide insights here.

Result Requested:

student_name      student_showed      class_name     class_started     class_held_date  
  Jeter             2022-02-05          Math           2022-02-05
  Jeter             2022-02-06          Math           2022-02-05        2022-02-06
  Jeter             2022-02-07          Math           2022-02-05        2022-02-07
  Jeter             2022-02-08          Math           2022-02-05
  Jeter             2022-02-09          Math           2022-02-05        2022-02-09
  Jeter             2022-02-05          English        2022-02-05
  Jeter             2022-02-06          English        2022-02-05        2022-02-06
  Jeter             2022-02-07          English        2022-02-05        2022-02-07
  Jeter             2022-02-08          English        2022-02-05
  Jeter             2022-02-09          English        2022-02-05        2022-02-09
  Soriano           2022-02-05          Math           2022-02-05
  Soriano           2022-02-06          Math           2022-02-05        2022-02-06
  Soriano           2022-02-07          Math           2022-02-05        2022-02-07
  Soriano           2022-02-08          Math           2022-02-05
  Soriano           2022-02-09          Math           2022-02-05        2022-02-09
  Soriano           2022-02-05          English        2022-02-05
  Soriano           2022-02-06          English        2022-02-05        2022-02-06
  Soriano           2022-02-07          English        2022-02-05        2022-02-07
  Soriano           2022-02-08          English        2022-02-05
  Soriano           2022-02-09          English        2022-02-05        2022-02-09

CodePudding user response:

You should be able to handle this using windowing.

select
student_name,
...
min (c.class_started) over (partition by student_name,class_name)
from
students as s
left join classes as c on s.class_name = c.class_name and s.student_showed = c.class_held_date

SQL Fiddle

CodePudding user response:

Not a sql expert. But here's another way.

select distinct
  s.student_name, 
  s.student_showed, 
  s.class_name, 
  (case when c.class_started is NULL then
    (select c1.class_started from classes c1 where c1.class_name = s.class_name limit 1)
       else c.class_started
  end) as "class_started", 
  c.class_held_date 
 from students s
 left join classes c
 on s.student_showed = c.class_held_date
  • Related