2016-10-16 18 views
0

私はホテルの部屋を予約するためのデータベースを作成しています。私は、ゲストの 'dateFrom'変数が特定のゲストの 'dateFrom'と 'dateTo'変数の間にあるかどうかをチェックする制約に固執しています。すなわち、ゲストは一度に1つ以上の部屋を予約することはできません。それはあなたが長期的な値を必要とするように私には見えます...私はPostgresのSQLを知らない心の中でSQLは存在しません(...(...)と...(...))

CREATE TABLE tomsBooking 
(
    hotelNo HotelNo NOT NULL, 
    guestNo INT NOT NULL, 
    dateFrom DATE NOT NULL, 
    dateTo DATE NOT NULL, 
    roomNo RoomNumber 

    CONSTRAINT GuestOverlap 
    CHECK (NOT EXISTS 
       (SELECT * FROM tomsBooking b 
           WHERE b.guestNo = b.guestNo 
           AND b.dateTo >= dateFrom 
           AND b.dateFrom <= dateTo 
          ) 
      ) 
); 
+0

@sstanああ、予約テーブルの最後にCONSTRAINTを置く方がいいですか? –

+0

@sstan代わりにCONSTRAINTを使用するように質問を更新しましたが、まだエラーが発生しています。私は今私が持っているもので質問を更新しました。 –

+1

この種のロジックは、依然としてチェック制約のためには複雑すぎます。チェック制約は、通常、単一の行のデータのみを検証することができます。私はPostgreSQLのエキスパートではありませんが、通常、この種の検証ロジックはトリガーでしか表現できないと思います。 – sstan

答えて

0

ベアリング:「チェック制約でサブクエリを使用することはできません」:

は、私はエラーを取得していますBETWEENステートメントの近くにあるので、比較はどの値をチェックしているかを知っています。しかし、代替として

、およびPostgresql query between date rangesに基づいて、私はこのようにそれを構築します:

CREATE DOMAIN DateFrom AS DATE 
    CHECK (VALUE > '2016-10-16' AND NOT EXISTS (SELECT * FROM tomsBooking b 
          WHERE b.guestNo = g.guestNo 
           AND VALUE >= dateFrom 
           AND VALUE <= dateTo 
          ) 
    ); 

私はあなたが私の提案を微調整する必要がありますので、私は、Postgresのを知らない、言うように。

+0

私はいくつかのオンラインドキュメントを探していましたが、あなたのソリューションはより良いと思いますが、私はまだエラーを受け取りました。 'チェック制約でサブクエリを使用できません' –

+0

https ://www.postgresql.org/docs/9.5/static/sql-createdomain.html –

+1

@Thomas sstanのコメントを見るエラーが示すように、チェック制約にサブクエリを使用することはできませんが、あなたの目的に合わせてDOMAINを使用すべきではないので、チェック制約は必要ありません。 –

4

残念ながら、Postgresはチェック制約のサブクエリをサポートしていません。

しかし、このケースであるがために作成された場所を正確に何exclusion constraintsです:

詳細および例については
CREATE TABLE tomsBooking 
(
    hotelNo HotelNo NOT NULL, 
    guestNo INT NOT NULL, 
    dateFrom DATE NOT NULL, 
    dateTo DATE NOT NULL, 
    roomNo RoomNumber 
); 

alter table tomsbooking 
    add constraint guestoverlap 
    exclude using gist (guestno with =, daterange(datefrom, dateto) with &&); 

、取扱説明書を参照:GISTのインデックスが使用できるようにするためにはhttps://www.postgresql.org/docs/current/static/rangetypes.html#RANGETYPES-CONSTRAINT

をあなたが使用してbtree_gistモジュールをインストールする必要があり=オペレータ:

create extension btree_gist; 

(dのみが必要であることをデータベースごとに1つ)

関連する問題