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

更新: レコードの小さなサブセットのみを取得する場合でも効率的になるように、2 つの外部結合を使用してクエリを書き直しました。

単一の日付と会場を最も効率的に取得する方法は次のとおりです。

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 に答える