2

我确定我可能只是健忘或过于复杂......但这是我的场景:

日历表(记录每年的每一天)

iso_date
01/01/01
02/01/01
03/01/01
04/01/01

场地表(每个场地的记录)

venue
All London
London Tower
London Bridge
Millenium Bridge

综合场地表(参考链接场地)

master_venue,     child_venue
All London,       All London
All London,       London Tower
All London,       London Bridge
All London,       Millenium Bridge
London Tower,     London Tower
London Bridge,    London Bridge
Millenium Bridge, Millenium Bridge

预订表(记录每次预订,包括日期和地点)

iso_date, venue,            event
01/01/01, All London,       1
02/01/01, London Tower,     2
02/01/01, Millenium Bridge, 3
04/01/01, London Bridge,    4

事件表

event, status
1,     1
2,     0
3,     1
4,     1

现在我想加入表格,这样我就可以得到每天每个场地的记录,无论它是否已被预订。如果场地有预订,我只想在活动状态为 1 时查看它。

输出

iso_date, venue,            booked
01/01/01, All London,       1
01/01/01, London Tower,     1
01/01/01, London Bridge,    1
01/01/01, Millenium Bridge, 1
02/01/01, All London,       0
02/01/01, London Tower,     0
02/01/01, London Bridge,    0
02/01/01, Millenium Bridge, 1
03/01/01, All London,       0
03/01/01, London Tower,     0
03/01/01, London Bridge,    0
03/01/01, Millenium Bridge, 0
04/01/01, All London,       0
04/01/01, London Tower,     0
04/01/01, London Bridge,    1
04/01/01, Millenium Bridge, 0

我不能在 where 子句中使用事件状态,因为它会完全删除记录。

我知道我可以使用子查询或一些复杂的案例语句,但是我可以智能地加入表来解决我的问题吗?

4

3 回答 3

6

你应该能够写:

SELECT Calendar.iso_date AS iso_date,
       Venues.venue AS venue,
       COALESCE(Events.status, 0) AS booked
  FROM Calendar
 CROSS
  JOIN Venues
  LEFT
 OUTER
  JOIN (      Bookings
         JOIN Events
           ON Events.event = Bookings.event
          AND Events.status = 1
       )
    ON Bookings.iso_date = Calendar.iso_date
   AND Bookings.venue = Venues.venue
;

(免责声明:未经测试。)

于 2012-12-13T14:14:49.437 回答
0

您需要从一个驱动表开始,它是日历和场地的交叉连接。然后,加入预订以获取预订信息:

select c.iso_date, v.venue,
       (case when b.event is NULL then 0 else 1 end) as Booked
from calendar c cross join
     venues v left outer join
     bookings b
     on b.iso_date = c.iso_date and
        b.venue = v.venue
于 2012-12-13T14:14:10.677 回答
0
select iso_date, 
       venue,
       max(case when events.event is not null then 1 else 0 end) as booked
    from calendar
    cross join venue
    left outer join bookings on
        bookings.date  = iso_date and
        bookings.venue = venue.venue
    left outer join events on 
        events.status = 1 and 
        events.event = bookings.event
    group by iso_date, venue

更新:用两个外连接重写了查询,这样即使只获取记录的一小部分,它也会很有效。

以下是您最有效地获得单一日期和地点的方法:

select iso_date, 
       venue,
       max(case when events.event is not null then 1 else 0 end) as booked
    from calendar
    inner join venue on
        calendar.iso_date = '01/01/01' and
        venue.venue = 'my front lawn'
    left outer join bookings on
        bookings.date  = iso_date and
        bookings.venue = venue.venue
    left outer join events on 
        events.status = 1 and 
        events.event = bookings.event
    group by iso_date, venue
于 2012-12-13T14:17:17.593 回答