加入两个表,但删除已存在于另一个表中的行

时间:2012-05-06 21:41:10

标签: sql postgresql join duplicates

我有四张桌子:

CREATE TABLE days (
day text priamry key
);

这些天运行mondaysaturday

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

时间从上午8:00到下午9:00(以小时为单位)。 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

我想要做的是为这三个法院列出所有未预约的时间 所以我会有一个像

这样的清单
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表中预订的子句。

感谢您就此事提出任何建议。

1 个答案:

答案 0 :(得分: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(与表格之间的逗号相同)daystimes以及activities。这些括号是多余的,因为表默认从左到右连接。

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)
   );