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

标签 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

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

所以它应该给我一个 result_set

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

最佳答案

all the Table_Tennis rooms that are not being used at a certain time on a certain day,

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

all rooms that have not yet been booked on all times for one day.

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

... because that would drop rooms with no entries for the day at all.


You might consider using

slot time

代替

time varchar(5)

time 不应用作标识符。这是一个 reserved word在所有 SQL 标准中和 PostgreSQL 中的类型名称。
此外,data type timevarchar(5) 更适合您的目的并且占用更少的空间。

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

instead of

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

工作日的名称可以覆盖一周。我想您想要的不止于此。

关于postgresql - 如何检查一张表中的某些内容是否未在另一张表中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10261372/

相关文章:

sql - SHA-256 哈希和 base64 编码

MySQL 使用外键创建表给出 errno : 150

mysql - 同一张表上的多个连接

ruby-on-rails - Rails 连接查询

ruby-on-rails - ActiveRecord 在 View 中呈现时结果不正确

mysql - 使用外键是否加速表连接

java - 如何在 Integer 列上的 Hibernate 中创建外键

php - 自动增量作为主键导致重复条目

sql - 合并具有 2 列主键的表中的记录

java - jOOQ 和 PostgreSQL : mapping nested json object extracted from complex jsonb into custom type