我有以下表格作为示例
球拍
--------------------
| id | Name |
| 1 | Raquet 1 |
| 2 | Raquet 2 |
--------------------
字符串
--------------------
| id | Name |
| 1 | String 1 |
| 2 | String 2 |
| 3 | String 3 |
| 4 | String 4 |
--------------------
标签
--------------------
| id | Name |
| 1 | Label 1 |
| 2 | Label 2 |
| 3 | Label 3 |
| 4 | Label 4 |
--------------------
Raquet_Labels
--------------------
| r_id | l_id |
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
--------------------
String_Labels
--------------------
| s_id | l_id |
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
| 3 | 3 |
| 4 | 3 |
| 4 | 4 |
--------------------
我想匹配所有列表中的所有Raquet,String组合,其中String应该具有相应Raquet的所有标签。
例如
Raquet 1有标签1,2 Raquet 2具有标签3,4
字符串1的标签为1,2,3 字符串2具有标签1,2 字符串3具有标签1,3 字符串4具有标签3,4
从上面 - 字符串1包含作为Raquet 1一部分的所有标签 字符串2包含作为Raquet 1一部分的所有标签 字符串3没有任何Raquet的标签 字符串4包含Raquet 2
的所有标签以下是期望
--------------------
| r_id | s_id |
| 1 | 1 |
| 1 | 2 |
| 2 | 4 |
--------------------
用于创建所需数据的SQL。
create table raquet(id integer not null, name varchar(256) not null);
insert into raquet values (1,'Raquet 1'), (2,'Raquet 2'), (3,’Raquet 3’);
create table string(id integer not null, name varchar(256) not null);
insert into string values (1,'String 1'), (2,'String 2'), (3,'String 3'), (4,'String 4');
create table label(id integer not null, name varchar(256) not null);
insert into label values (1,'Label 1'), (2,'Label 2'), (3,'Label 3'), (4,'Label 4');
create table raquet_labels(r_id integer not null, l_id integer not null);
insert into raquet_labels values (1,1), (1,2), (2,3), (2,4);
create table string_labels(s_id integer not null, l_id integer not null);
insert into string_labels values (1,1), (1,2), (1,3), (2,1), (2,2), (3,1), (3,3), (4,3), (4,4);
答案 0 :(得分:0)
这项任务看起来很容易,但并非如此。这是一种方式:
count(*)
计算所有记录,但count(<column from the outer-joined table>)
仅统计匹配。计数是否相等(每个标签匹配)或不。查询:
select rl.r_id, s.id as s_id
from raquet_labels rl
cross join string s
left join string_labels sl on sl.s.id = s.id and sl.l_id = rl.l_id
group by rl.r_id, s.id
having count(*) = count(sl.s_id);
这是另一种方式:
查询:
select r.id as r_id, s.id as s_id
from racket r
cross join string s
where not exists
(
select l_id from raquet_labels rl where rl.r_id = r.id
except
select l_id from string_labels sl where sl.s_id = s.id
);