如何检查一个表中的某些内容是否未在另一个表中使用

时间:2012-04-21 17:33:53

标签: postgresql foreign-keys primary-key

我有三张桌子:

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

我想知道有可能找到所有在某一天特定时间没有使用的Table_Tennis房间,或者所有房间在一天内没有预订的所有房间。

所以它应该给我一个<_ p>的result_set

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

1 个答案:

答案 0 :(得分:1)

  

所有未在特定时间使用的Table_Tennis会议室   在某一天,

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

但不是:


SELECT activity
FROM   activities a
JOIN (
    SELECT activity
    FROM   planner p
    WHERE  day = 'friday'
    GROUP BY 1
    HAVING count(*) < 12
    ) p USING (activity);

...因为那会使当天没有参赛作品的房间掉落。


您可以考虑使用

slot time

而不是

time varchar(5)
不应将

time用作标识符。它是所有SQL标准中的reserved word和PostgreSQL中的类型名称 此外,data type time更适合您的目的,占用的空间比varchar(5)少。

并且

 day date foreign key ...
,slot time foreign key ...

而不是

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

工作日的名字会让你涵盖一周。我假设你想要更多。