左连接到两个内连接表

Lee*_*ett 1 sql sql-server

我敢肯定我可能只是在忘记或过于复杂......但这是我的情景:

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

iso_date
01/01/01
02/01/01
03/01/01
04/01/01
Run Code Online (Sandbox Code Playgroud)

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

venue
All London
London Tower
London Bridge
Millenium Bridge
Run Code Online (Sandbox Code Playgroud)

复合场地桌(参考相关场地)

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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

事件表

event, status
1,     1
2,     0
3,     1
4,     1
Run Code Online (Sandbox Code Playgroud)

现在我想加入这些表格,这样我每天都可以获得每个场地的记录,无论是否已经预订.如果场地有预订,我只想在事件状态为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
Run Code Online (Sandbox Code Playgroud)

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

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

rua*_*akh 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
;
Run Code Online (Sandbox Code Playgroud)

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