MySQL LEFT OUTER JOIN有一些最终结果问题

时间:2015-10-18 00:24:24

标签: mysql sql join

我有2张桌子 表1:tbl_appointments
表2:tbl_appointmentschedule_details

Table1
AppointmentTypeID | AppointmentTimeID | AppointmentDate | NumberOfApplicants ----------------------------------------------------------------------------- 11 23 10-16-2015 1 11 23 10-16-2015 1 11 24 10-16-2015 1 11 24 10-16-2015 1 11 23 10-16-2015 1 11 24 10-16-2015 1 11 25 10-16-2015 1 11 22 10-17-2015 1 11 22 10-17-2015 1 11 22 10-17-2015 1 11 22 10-17-2015 1
Table2
ScheduleID | AppointmentTimeID ---------------------------- 27 22 27 23 27 24 27 25 27 26
  1. 我希望Table2中的所有AppointmentTimeID都与table1匹配,并在最终结果中显示这些table2.AppointmentTimeID是否与table1.AppointmentTimeID匹配,但应显示日期和零NumberOfApplicants。
  2. 然后我希望它应该在table1.AppointmentDate的日期之间使用' 2015-10-15'和' 2015-10-15'。
  3. 我的最终结果应该是每天的table2中的所有值以及table1.NumberOfApplicats的总和。
  4. 请看我的最终结果应该是这样的
  5. 以下查询我正在使用

    SELECT ad.AppointmentTimeID, COALESCE(sum(a.NumberOfApplicants),0) AS TBooked, a.AppointmentDate <br>FROM tbl_appointmentschedule_details ad
    LEFT OUTER JOIN tbl_appointments a
    ON ad.AppointmentTimeID = a.AppointmentTimeID
    AND (a.AppointmentDate BETWEEN '2015-10-16' AND '2015-10-17')
    AND ad.ScheduleID = 27
    AND a.AppointmentTypeID = 11
    WHERE a.AppointmentDate IS NOT NULL
    GROUP BY a.AppointmentDate, ad.AppointmentTimeID
    ORDER BY a.AppointmentDate ASC
    

    它只显示table1中与appointmenttimeid匹配的那些记录,但我希望看到所有记录。

    FINAL RESULTS I WANT SHOULD BE

    AppointmentTimeID | AppointmentDate | NumberOfApplicants --------------------------------------------------------- 22 16-10-2015 0 23 16-10-2015 3 24 16-10-2015 3 25 16-10-2015 1 26 16-10-2015 0 22 17-10-2015 4 23 17-10-2015 0 24 17-10-2015 0 25 17-10-2015 0 26 17-10-2015 0

    我的查询仅显示那些具有类似

    值的记录

    MY QUERY OUTPUT

    AppointmentTimeID | AppointmentDate | NumberOfApplicants --------------------------------------------------------- 23 16-10-2015 3 24 16-10-2015 3 25 16-10-2015 1 22 17-10-2015 4

    请帮我解决这个问题。

4 个答案:

答案 0 :(得分:0)

将过滤条件放在WHERE子句中,而不是JOIN

SELECT ad.AppointmentTimeID, COALESCE(sum(a.NumberOfApplicants), 0) AS TBooked, a.AppointmentDate
FROM tbl_appointmentschedule_details ad
LEFT OUTER JOIN tbl_appointments a ON ad.AppointmentTimeID = a.AppointmentTimeID
WHERE a.AppointmentDate IS NOT NULL
    AND (a.AppointmentDate BETWEEN '2015-10-16' AND '2015-10-17')
    AND ad.ScheduleID = 27
    AND a.AppointmentTypeID = 11
GROUP BY a.AppointmentDate, ad.AppointmentTimeID
ORDER BY a.AppointmentDate ASC

答案 1 :(得分:0)

这应该适合你:

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

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 |

为了加快速度,你可能会受益于一些索引:

create index idx_tbl_appointments_apptdate_timeid on tbl_appointments(AppointmentDate, AppointmentTimeID);

create index idx_tbl_appointmentschedule_details_TimeID on tbl_appointmentschedule_details(AppointmentTimeID);

查询修改:

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

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

请注意,我在此查询中的两个位置添加了日期范围。了解此查询如何为您执行。

答案 2 :(得分:0)

select a.AppointmentTimeID, 
  a.AppointmentDate,coalesce(sum(ap.NumberOfApplicants),0) as NoOfApplicants
  from tbl_appointments a where exists
 (select 1 from tbl_appointmentschedule_details d where d.AppointmentTimeID = a.AppointmentTimeID )
 left join tbl_appointments ap
 on ap.AppointmentTimeID = a.AppointmentTimeID
  and ap.AppointmentDate = a.AppointmentDate
where a.AppointmentDate between '2015-10-16' and '2015-10-17'
group by a.AppointmentDate, a.AppointmentTimeID
order by a.AppointmentDate, a.AppointmentTimeID

我们可以尝试此查询。如果有任何问题,请告诉我

答案 3 :(得分:0)

这会返回您想要的内容:

select t4.AppointmentTimeID, t4.AppointmentDate,ifnull(t5.NumberOfApplicants,0)
from
    (SELECT t2.AppointmentTimeID,t3.AppointmentDate
    FROM sagemor.tbl_appointmentschedule_details t2, (SELECT t1.AppointmentDate FROM tbl_appointments t1 WHERE t1.AppointmentDate between '2015-10-16' and '2015-10-17' GROUP BY t1.AppointmentDate) t3) t4
left join 
    (SELECT t2.AppointmentTimeID,t1.AppointmentDate,sum(t1.NumberOfApplicants) as 'NumberOfApplicants'
    FROM tbl_appointmentschedule_details t2
    LEFT JOIN tbl_appointments t1 on t2.AppointmentTimeID=t1.AppointmentTimeID
    GROUP BY t2.AppointmentTimeID,t1.AppointmentDate) t5 
on t4.AppointmentDate=t5.AppointmentDate and t4.AppointmentTimeID=t5.AppointmentTimeID
order by t4.AppointmentDate,t4.AppointmentTimeID;

结果:

enter image description here

获得所需输出的另一种方法

select t4.AppointmentTimeID, t4.AppointmentDate,ifnull(t5.NumberOfApplicants,0)
from
    (select distinct t2.AppointmentTimeID, t1.AppointmentDate
  from tbl_appointments t1, tbl_appointmentschedule_details t2 WHERE t1.AppointmentDate between '2015-10-16' and '2015-10-17')  t4
left join 
    (SELECT t2.AppointmentTimeID,t1.AppointmentDate,sum(t1.NumberOfApplicants) as 'NumberOfApplicants'
    FROM tbl_appointmentschedule_details t2
    LEFT JOIN tbl_appointments t1 on t2.AppointmentTimeID=t1.AppointmentTimeID
    GROUP BY t2.AppointmentTimeID,t1.AppointmentDate) t5 
on t4.AppointmentDate=t5.AppointmentDate and t4.AppointmentTimeID=t5.AppointmentTimeID
order by t4.AppointmentDate,t4.AppointmentTimeID;