Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL LEFT OUTER JOIN ha problemi con i risultati finali

Questo dovrebbe farlo per te:

select 
  m.AppointmentTimeID, 
  m.AppointmentDate, 
  coalesce(sum(ap.NumberOfApplicants),0) as NoOfApplicants

from (
  -- just basically doing a cross to get all time/date combinations
  select distinct d.AppointmentTimeID, a.AppointmentDate
  from tbl_appointments a, tbl_appointmentschedule_details d
) m

left join tbl_appointments ap 
  on ap.AppointmentTimeID = m.AppointmentTimeID
  and ap.AppointmentDate = m.AppointmentDate

where m.AppointmentDate between '2015-10-16' and '2015-10-17'

group by m.AppointmentDate, m.AppointmentTimeID
order by m.AppointmentDate, m.AppointmentTimeID

Esempio SQLFiddle:http://sqlfiddle.com/#!9/1e632/15

Results:
| AppointmentTimeID |           AppointmentDate | NoOfApplicants |
|-------------------|---------------------------|----------------|
|                22 | October, 16 2015 00:00:00 |              0 |
|                23 | October, 16 2015 00:00:00 |              3 |
|                24 | October, 16 2015 00:00:00 |              3 |
|                25 | October, 16 2015 00:00:00 |              1 |
|                26 | October, 16 2015 00:00:00 |              0 |
|                22 | October, 17 2015 00:00:00 |              4 |
|                23 | October, 17 2015 00:00:00 |              0 |
|                24 | October, 17 2015 00:00:00 |              0 |
|                25 | October, 17 2015 00:00:00 |              0 |
|                26 | October, 17 2015 00:00:00 |              0 |

Per velocizzare un po' le cose, potresti trarre vantaggio da un po' di indicizzazione:

create index idx_tbl_appointments_apptdate_timeid on tbl_appointments(AppointmentDate, AppointmentTimeID);

create index idx_tbl_appointmentschedule_details_TimeID on tbl_appointmentschedule_details(AppointmentTimeID);

Modifica della query:

select 
  m.AppointmentTimeID, 
  m.AppointmentDate, 
  coalesce(sum(ap.NumberOfApplicants),0) as NoOfApplicants
from (
  select distinct AppointmentTimeID, AppointmentDate 
  from (select distinct AppointmentTimeID from tbl_appointmentschedule_details) one
  cross join
  (select distinct AppointmentDate from tbl_appointments
   where AppointmentDate between '2015-10-16' and '2015-10-17') two
) m
left join tbl_appointments ap 
  on ap.AppointmentTimeID = m.AppointmentTimeID
  and ap.AppointmentDate = m.AppointmentDate
where m.AppointmentDate between '2015-10-16' and '2015-10-17'
group by m.AppointmentDate, m.AppointmentTimeID
order by m.AppointmentDate, m.AppointmentTimeID

Esempio SQLFiddle:http://sqlfiddle.com/#!9/0de6d7/1

Si noti che ho aggiunto l'intervallo di date in due posizioni in questa query. Guarda come si comporta questa query per te.