2009-06-12 19 views
5

私は2つのテーブルを持っています.1つはオープニング用、もう1つは予約用です。予約テーブルのエントリは常に開口部を参照し、各開口部に複数の予約がある可能性があります。私はbookingType 'C'とは異なる予約をしているすべての開口部を抽出したいと思います。SQLクエリ - どこが間違っていますか?

など。結果に

  1. 開口がタイプA、B及びCの3つの予約を持っている場合、それは を示さないべきでは

  2. 開口がタイプAおよびBののみの予約を持っている場合、それが表示されるはず 結果における最大

は、私が試したものですが、それは例1で失敗したとして、それは正しくありません。

ここで
select op.id, bo.id 
    from opening op 
    left join booking bo on bo.openingId = op.id 
    where bo.bookingType != 'C'; 

は、完全なクエリは、時間間隔を参照している:

select op.id, bo.id 
    from opening op 
    left join booking bo on bo.openingId = op.id 
    where ((bo.arrivalDate < '2009/06/20' AND bo.departureDate <= '2009/06/20') OR 
     (bo.arrivalDate >= '2009/06/27' AND bo.departureDate > '2009/06/27')) 

私はbookingTypeは、実際には2つの列arrivalDatedepartureDateによって定義された時間間隔だった呼び出すために使用したもの:私はすべての必要とする上記の例では、 20th June 200927th June 2009の間に予約がありません。日付変更と

+0

SELECT op.id FROM opening op LEFT OUTER JOIN booking b ON op.id = b.openingid AND b.bookingtype = 'C' WHERE b.OpeningID IS NULL 

と、この:次のように - あなたは左反半にも参加を使用することができますか?宿題のようにも聞こえます。 –

+0

TABLE開口 IDのINT NULL NOT 説明VARCHAR(60) PRIMARY KEY(ID)、NOT NULL 表予約 IDのINT、 openingId INT NOT NULL、 arrivalDate DATETIME NULL NOT、 departureDate DATETIME NOT NULL、 PRIMARY KEY(id) 特定の日付間隔(例えば、20-06-2009から27-06-2009まで)で利用可能なすべてのオープニングを抽出しようとしています –

+0

上記の例のbookingTypeはどこですか? – akf

答えて

7
SELECT op.id 
FROM opening op 
WHERE op.id NOT IN 
    (SELECT b.openingid 
     FROM booking b 
     WHERE b.bookingtype='C') 

SELECT op.id 
FROM opening op 
WHERE op.id NOT IN 
    (SELECT b.openingid 
     FROM booking b 
     WHERE (b.arrivalDate BETWEEN '2009/06/20' AND '2009/06/27') 
      OR 
      (b.departureDate BETWEEN '2009/06/20' and '2009/06/27') 
    ) 
+0

これは私が避けようとしていたものです...サブクエリは少し重く聞こえますが、正常に動作します。 –

+0

aaronの左結合構文解も考慮してください。左結合は、サブクエリにない結合よりも高速であることが多い。 – HLGEM

+0

良いSQLデータベースは通常、左の結合にサブクエリを最適化して、同じパフォーマンスを持ちます。サブクエリを使用して文を記述します。コードを記述し理解することはより簡単です。 –

0
select opid, boid from 
    (select op.id opid, bo.id boid, bo.bookingType bookingType 
     from 
     openings op left outer join bookings bo on op.id = bo.id 
    ) 
where bookingType <> 'C' 
+0

-1サブクエリはここで何もしませんか? – Andomar

+0

実際には、左外部結合を行います。そしてメインクエリは、左外部結合の結果をフィルタリングします。 –

+0

しかし、左外部結合は、サブクエリなしで行うことができますか? – Andomar

2

ここで合流することなく、簡単にバージョンだ、あなたも開口テーブルは必要ありません。

select openingId, id 
from booking 
where openingId not in (
    select openingId 
    from booking 
    where bookingType = 'C' 
) 
1

@Frankie - なしNOT IN句が必要です。あなたのテーブル構造を持っていますか

SELECT op.id 
FROM opening op 
LEFT OUTER JOIN booking b ON op.id = b.OpeningID 
AND b.ArrivalDate BETWEEN '2009/06/20' AND '2009/06/27' 
AND b.DepartureDate BETWEEN '2009/06/20' AND '2009/06/27' 
WHERE b.OpeningID IS NULL 
関連する問題