2

私は4つのテーブルを持っています:

日々

CREATE TABLE days (
day text priamry key
);

最近はに実行mondayされsaturdayます。

時間

CREATE TABLE times (
time time Primary Key,
peak text 
);

時間枠で午前8時から午後9時までの時間(例:8:00、9:00、10:00、11:00)

活動

CREATE TABLE activities (
activity text primary key
);

とプランナー

CREATE TABLE planner (
day text foriegn key references days (day)
time time foriegn key references times (time)
activity text foriegn key references activities (activity)
member bigint
primary key (day, time, member)
);

プランナーテーブルには、次のようなデータが含まれます。

friday, 09:00, squash_court1 , 2
friday, 09:00, squash_court2 , 3
friday, 09:00, squash_court3 , 1

私がやりたいことは、これら3つの裁判所の予約されていないすべての時間のリストを作成するので、次のようなリストがあります。

time  activity
08:00 squash_court1
10:00 squash_court1
...rest of times...
08:00 squash_court2
10:00 squash_court2
...rest of times...
08:00 squash_court3
10:00 squash_court3
...rest of times...

8:00から10:00の間に9:00がない理由は、予約されているためです。

編集

現在、私は次の基本的な結合を持っています:

SELECT time , activity FROM times, activities;

今必要なのは、テーブルWHEREで予約されているものを削除する句です。planner

この件についてアドバイスをありがとうございます。

4

1 に答える 1

3

今必要なのは、テーブルWHEREで予約されているものを削除する句です。planner

これはさまざまな方法で実行できます。LEFT JOIN / WHERE .. IS NULL多くの場合、PostgreSQLで最速の計画を作成します。

SELECT t.time, a.activity
FROM   (days d CROSS JOIN  times t CROSS JOIN activities a)
LEFT   JOIN planner p ON (p.day, p.time, p.activity)
                       = (d.day, t.time, a.activity)
WHERE  p.activity IS NULL;

かっこを使用して、(テーブル間のコンマと同じように)最初に実行することを明確にCROSS JOINします。テーブルはデフォルトで左から右に結合されるため、これらの括弧は冗長です。daystimesactivities

条件は、次のJOIN短い形式です。

 ON p.day = d.day
AND p.time = t.time
AND p.activity = a.activity

別の方法は、NOT EXISTS半結合です。

SELECT t.time, a.activity
FROM   (days d CROSS JOIN  times t CROSS JOIN activities a)
WHERE  NOT EXISTS (
   SELECT *
   FROM   planner 
   WHERE (p.day, p.time, p.activity)
       = (d.day, t.time, a.activity)
   );
于 2012-05-06T22:27:11.727 に答える