SQL N:M 按中间表中的条件标志查询合并结果
发布时间:2022-08-22 15:32:48 306
相关标签: # 数据库
[首先,如果这是重复的,抱歉,我找不到对此的回应,因为这是对 ORM 限制的奇怪解决方案,而且我显然是 SQL 的菜鸟]
域名要求:
- 一个旅必须由一名用户(政委)和可选的一名且仅一名助理(1:1)组成
- 一个用户只能是一个旅的一部分 (1:1)
CREATE TABLE Users
(
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(100) NOT NULL
);
CREATE TABLE Brigades
(
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
-- N:M relationship with a flag inside which determine if that user is a commissar or not
CREATE TABLE Brigade_User
(
brigade_id INT NOT NULL REFERENCES Brigades(id)
ON DELETE CASCADE
ON UPDATE CASCADE,
user_id INT NOT NULL REFERENCES Users(id)
ON DELETE CASCADE
ON UPDATE CASCADE,
is_commissar BOOLEAN NOT NULL
PRIMARY KEY(brigade_id, user_id)
);
理想情况下,由于关系是 1:1,Brigade_User 中间表可以被删除,而可以创建一个具有两个外键的 Brigade 表(这不受Diesel Rust ORM支持,所以我认为我与第一种方法相结合)
CREATE TABLE Brigades
(
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL
-- 1:1
commisar_id INT NOT NULL REFERENCES Users(id)
ON DELETE CASCADE
ON UPDATE CASCADE,
-- 1:1
assistant_id INT NOT NULL REFERENCES Users(id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
示例:
> SELECT * FROM brigade_user LEFT JOIN brigades ON brigade_user.brigade_id = brigades.id;
brigade_id | user_id | is_commissar | id | name
------------+---------+--------------+----+------------------
1 | 1 | t | 1 | Patrulla gatuna
1 | 2 | f | 1 | Patrulla gatuna
2 | 3 | t | 2 | Patrulla perruna
2 | 4 | f | 2 | Patrulla perruna
3 | 6 | t | 3 | Patrulla canina
3 | 5 | f | 3 | Patrulla canina
(4 rows)
是否可以进行一个返回如下表的查询?
brigade_id | commissar_id | assistant_id | name
-----------+--------------+--------------+--------------------
1 | 1 | 2 | Patrulla gatuna
2 | 3 | 4 | Patrulla perruna
3 | 6 | 5 | Patrulla canina
请注意,每两行已合并为一行(请记住,一个旅由一个小卖部和一个助理组成,可选),具体取决于国旗。
是否可以改进此模型(考虑到对引用同一表的多个外键的限制,已讨论在这里)
特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报