我有四张桌子:
天
CREATE TABLE days (
day text priamry key
);
这些天运行monday
到saturday
。
次
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
表中预订的子句。
感谢您就此事提出任何建议。
答案 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
(与表格之间的逗号相同)days
和times
以及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)
);