如何select 使用三个表的差异?
How to select differences using three tables?
我需要 运行 一个脚本来修复我的 table company_menu 中的一些行。
但是,我无法构建此查询来获取这些寄存器。
我在此 link 中构建架构:http://sqlfiddle.com/#!9/5ab86b
下面我展示了预期的结果。
公司
id
name
1
company 1
2
company 2
3
company 3
menu_items
id
name
1
home
2
charts
3
users
4
projects
company_menu
id
company_id
menu_item_id
1
1
1
2
1
2
3
1
3
4
1
4
5
2
1
6
2
3
这是我预期的结果:
id
company_id
menu_item_id
1
2
2
2
2
4
3
3
1
4
3
2
5
3
3
6
3
4
CREATE TABLE companies(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50)
);
CREATE TABLE menu_items(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50)
);
CREATE TABLE company_menu(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
company_id INT,
menu_item_id INT,
FOREIGN KEY(company_id) REFERENCES companies(id),
FOREIGN KEY(menu_item_id) REFERENCES menu_items(id)
);
INSERT INTO companies (name) VALUES ("Company 1"),("Company 2"),("Company 3");
INSERT INTO menu_items (name) VALUES ("home"),("charts"),("users"),("projects");
INSERT INTO company_menu (company_id, menu_item_id) VALUES (1, 1),(1, 2),(1,3),(1,4);
INSERT INTO company_menu (company_id, menu_item_id) VALUES (2, 1),(2,3);
我能想到的两种方式。不知道哪个效率更高。两者都是从全compannies-menu_items join开始得到所有可能的组合,然后切出现有的:
WHERE NOT EXISTS
select c.id company_id, m.id menu_item_id
from companies c
join menu_items m
where not exists (
select * from company_menu where company_id = c.id and menu_item_id = m.id
);
LEFT JOIN
+ IS NULL
:
select c.id company_id, m.id menu_item_id
from companies c
join menu_items m
left join company_menu cm on cm.company_id = c.id and cm.menu_item_id = m.id
where cm.id is null;
两者都可以在任何公司或 menu_item 列中排序。
我需要 运行 一个脚本来修复我的 table company_menu 中的一些行。 但是,我无法构建此查询来获取这些寄存器。 我在此 link 中构建架构:http://sqlfiddle.com/#!9/5ab86b
下面我展示了预期的结果。
公司
id | name |
---|---|
1 | company 1 |
2 | company 2 |
3 | company 3 |
menu_items
id | name |
---|---|
1 | home |
2 | charts |
3 | users |
4 | projects |
company_menu
id | company_id | menu_item_id |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 1 | 3 |
4 | 1 | 4 |
5 | 2 | 1 |
6 | 2 | 3 |
这是我预期的结果:
id | company_id | menu_item_id |
---|---|---|
1 | 2 | 2 |
2 | 2 | 4 |
3 | 3 | 1 |
4 | 3 | 2 |
5 | 3 | 3 |
6 | 3 | 4 |
CREATE TABLE companies(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50)
);
CREATE TABLE menu_items(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50)
);
CREATE TABLE company_menu(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
company_id INT,
menu_item_id INT,
FOREIGN KEY(company_id) REFERENCES companies(id),
FOREIGN KEY(menu_item_id) REFERENCES menu_items(id)
);
INSERT INTO companies (name) VALUES ("Company 1"),("Company 2"),("Company 3");
INSERT INTO menu_items (name) VALUES ("home"),("charts"),("users"),("projects");
INSERT INTO company_menu (company_id, menu_item_id) VALUES (1, 1),(1, 2),(1,3),(1,4);
INSERT INTO company_menu (company_id, menu_item_id) VALUES (2, 1),(2,3);
我能想到的两种方式。不知道哪个效率更高。两者都是从全compannies-menu_items join开始得到所有可能的组合,然后切出现有的:
WHERE NOT EXISTS
select c.id company_id, m.id menu_item_id
from companies c
join menu_items m
where not exists (
select * from company_menu where company_id = c.id and menu_item_id = m.id
);
LEFT JOIN
+IS NULL
:
select c.id company_id, m.id menu_item_id
from companies c
join menu_items m
left join company_menu cm on cm.company_id = c.id and cm.menu_item_id = m.id
where cm.id is null;
两者都可以在任何公司或 menu_item 列中排序。