1

我有三张桌子:

CREATE TABLE activities (
activity varchar(20) Primary key
);

有数据:

Table_Tennis1
Table_Tennis2
Table_Tennis3

CREATE TABLE times (
time varchar(5)
);

有数据

09:00
10:00
11:00
12:00
13:00
14:00
15:00
16:00
17:00
18:00
19:00
20:00

最后

CREATE TABLE planner (
day varchar(9) foreign key
time varchar(5) foreign key
activity varchar(20) foreign key
member bigint foreign key
);

和主键=(天,时间,活动)

有数据

friday,09:00,Table_Tennis1,4
friday,10:00,Table_Tennis2,2

我想知道是否有可能找出在某一天的某个时间没有使用的所有乒乓球室,或者在某一天的所有时间都没有被预订的所有房间。

所以它应该给我一个 result_set

09:00, Table_Tennis2, Table_Tennis3
10:00, Table_Tennis1, Table_Tennis3
11:00, Table_Tennis1, Table_Tennis2, Table_Tennis3 ect ect
4

1 回答 1

1

某一天某一时间未使用的所有乒乓球室,

SELECT activity
FROM   activities a
WHERE  NOT EXISTS (
    SELECT *
    FROM   planner p
    WHERE  p.activity ~~ 'Table_Tennis%' -- may or may not be needed
    AND    p.day  = 'friday'
    AND    p.time = '09:00'
    AND    p.activity = a.activity -- was missing in my 1st draft
    );

一天内所有时间尚未预订的所有房间。

SELECT a.activity
FROM   activities a
LEFT JOIN (
    SELECT activity
    FROM   planner p
    WHERE  day = 'friday'
    GROUP  BY 1
    HAVING count(*) = 12 -- assuming there are exactly 12 slots
    ) p USING (activity)
WHERE p.activity IS NULL; -- excludes all fully booked rooms

或者:

SELECT activity
FROM   activities a
WHERE NOT EXISTS (
    SELECT activity
    FROM   planner p
    WHERE  day = 'friday'
    GROUP  BY 1
    HAVING count(*) = 12 -- assuming there are exactly 12 slots
    );

但不是:


选择活动
FROM 活动
加入 (
    选择活动
    来自计划者 p
    WHERE day = '星期五'
    按 1 分组
    计数 (*) < 12
    ) p 使用(活动);

...因为那会丢弃当天没有条目的房间。


您可以考虑使用

slot time

代替

time varchar(5)

time不应用作标识符。它是所有 SQL 标准中的保留字,也是 PostgreSQL 中的类型名称。
此外,数据类型time更适合您的目的,并且占用的空间比varchar(5).

日期键...
, 时隙外键 ...

代替

 day varchar(9) foreign key ...
,time varchar(5) foreign key ...

工作日的名称可以让你覆盖一周。我想你想要的不止这些。

于 2012-04-21T18:10:55.557 回答