合并相关记录

时间:2013-02-21 06:06:16

标签: mysql sql

我有这个MySQL查询:

select day(ReservationDate) as ReservationDay, sum(SleighSeats) as SleighSeats, sum(CabSeats) as CabSeats, 0 as IsFullMoon, '' as OverrideText
from Reservations
where month(ReservationDate) = 2
group by ReservationDate
union
select day(CalendarDate) as ReservationDay, 0 as SleighSeats, 0 as CabSeats, IsFullMoon, OverrideText
from CalendarOverrides
where month(CalendarDate) = 2
group by CalendarDate
order by ReservationDay

“预订”表可以包含任何给定日历日期的任意数量的记录,或者根本不包含任何记录。 CalendarOverrides表可以包含每个日历日期的1或0条记录。我试图将结果合并在一起,但并没有完全正确。

这是我的结果集:

enter image description here

预订第23天是问题所在。我想将这2条记录合并为1,这样5个值就是:
23,6,8,1,[空白/ null]

澄清:
- ReservationDay在两个表中(在CalendarOverrides中命名为CalendarDate)
- SleighSeats和CabSeats仅存在于预订表中 - IsFullMoon和OverrideText仅存在于CalendarOverrides表中

联合中的顶级查询已经合并了同一ReservationDay上的所有预订记录,但是如何将底部查询中的任何记录与顶部查询中的记录合并为同一Re​​servationDay? (因此,任何一天都不会有超过1条记录。)

2 个答案:

答案 0 :(得分:2)

select 
    ReservationDay, 
    max(SleighSeats) as SleighSeats, 
    max(CabSeats) as CabSeats, 
    max(IsFullMoon) as IsFullMoon,
    max(OverrideText) as OverrideText
from (

    select 
        day(ReservationDate) as ReservationDay, 
        sum(SleighSeats) as SleighSeats, 
        sum(CabSeats) as CabSeats, 
        0 as IsFullMoon, 
        '' as OverrideText
    from Reservations
    where month(ReservationDate) = 2
    group by ReservationDate
    union
    select 
        day(CalendarDate) as ReservationDay, 
        0 as SleighSeats, 
        0 as CabSeats, 
        IsFullMoon, 
        OverrideText
    from CalendarOverrides
    where month(CalendarDate) = 2
    group by CalendarDate, IsFullMoon, OverrideText
) as subtbl 
group by ReservationDay
order by ReservationDay, IsFullMoon

答案 1 :(得分:0)

select day(ReservationDate) as ReservationDay, sum(SleighSeats) as SleighSeats,
    sum(CabSeats) as CabSeats, COALESCE(IsFullMoon,0) as IsFullMoon,
    COALESCE(OverrideText,'') as OverrideText
from Reservations
left outer join CalendarOverrides 
    ON Reservations.ReservationDate = CalendarOverrides.CalendarDate
where month(ReservationDate) = 2
group by ReservationDate, IsFullMoon, OverrideText

union all

select day(CalendarDate) as ReservationDay, 0 as SleighSeats, 
    0 as CabSeats, IsFullMoon, 
    OverrideText
from CalendarOverrides
where month(CalendarDate) = 2
and NOT EXISTS
(
    SELECT 1 
    FROM Reservations 
    WHERE Reservations.ReservationDate = CalendarOverrides.CalendarDate
)

order by ReservationDay

如果您的RDBMS支持它,您也应该能够完全加入(由于where子句中的COALESCE,这可能会更慢):

select day(COALESCE(ReservationDate, CalendarDate)) as ReservationDay,
    COALESCE(sum(SleighSeats),0) as SleighSeats,
    COALESCE(sum(CabSeats),0) as CabSeats, COALESCE(IsFullMoon,0) as IsFullMoon,
    COALESCE(OverrideText,'') as OverrideText
from Reservations
full join CalendarOverrides 
    ON Reservations.ReservationDate = CalendarOverrides.CalendarDate
where month(COALESCE(ReservationDate, CalendarDate)) = 2
group by ReservationDate, CalendarDate, IsFullMoon, OverrideText
order by ReservationDay