Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mysql query to join 4 tables based on multiple criteria

Tags:

join

mysql

I have four tables in mysql as below:

enter image description here

enter image description here

What I want to do is join the tables together to show if the training has been done for each user in a department, if it has been done show the date of training else say training needed.

so desired output for department finance would be something like:

enter image description here

I have tried with the below code but the joins become inaccurate and invalid.

select o.person, o.job, j.risk, r. training,c.course,
    c.person,c.datecompleted 
from orgstructure o 
left outer join jobsrisks j 
    on o.job=j.job 
left outer join risktraining r 
    on j.risk=r.risk 
left outer join coursescompleted c 
    on o.person=c.person 
where o.department='finance'

should I be embedding multiple select queries into one? any help is appreciated.

like image 501
Smudger Avatar asked Dec 07 '22 10:12

Smudger


1 Answers

I am going to guess that that issue is that you are joining the orgstructure to coursescompleted by person only, I think you also need to join on training:

select o.person, 
  o.job, 
  j.risk, 
  r.training,
  c.course,
  c.person,
  c.datecompleted 
from orgstructure o 
left outer join jobsrisks j 
  on o.job=j.job 
left outer join risktraining r 
  on j.risk=r.risk 
left outer join coursescompleted c 
  on o.person=c.person 
  and r.training = c.course   --- add this
where o.department='finance'

You need to join on the person plus if that person has a completed the course for each risk associated with the job.

Putting the entire query together you will have:

select o.person, 
  o.job, 
  j.risk, 
  r.training,
  case when c.course is null then 'no' else 'yes' end TrainingCompleted,
  coalesce(c.datecompleted, 'n/a') datecompleted
from orgstructure o 
left outer join jobsrisks j 
  on o.job=j.job 
left outer join risktraining r 
  on j.risk=r.risk 
left outer join coursescompleted c 
  on o.person=c.person 
  and r.training = c.course   
where o.department='finance'

See SQL Fiddle with Demo

The result is:

|        PERSON |        JOB |                     RISK |                  TRAINING | TRAININGCOMPLETED |       DATECOMPLETED |
-------------------------------------------------------------------------------------------------------------------------------
| taylor chetty |    manager |                   safety |          induction course |                no |                 n/a |
| taylor chetty |    manager |                 security |           security course |                no |                 n/a |
| bill thompson | data clerk |              bad posture | personal wellbeing course |                no |                 n/a |
| bill thompson | data clerk | repetitive strain injury |            nursing course |               yes | 2000-04-13 00:00:00 |
| bill thompson | data clerk |                   safety |          induction course |               yes | 2007-12-04 00:00:00 |
|     ann brown | data clerk |              bad posture | personal wellbeing course |                no |                 n/a |
|     ann brown | data clerk | repetitive strain injury |            nursing course |                no |                 n/a |
|     ann brown | data clerk |                   safety |          induction course |                no |                 n/a |
like image 180
Taryn Avatar answered Dec 10 '22 12:12

Taryn