我有两个表:segment(id,name)和parts(id,name)。这两个具有n:m关系,因此段可以有多个部分,一个部分可以属于多个部分。
当然,我们有一个链接表segments_parts(segments_id,parts_id)来将这两者连接在一起,这与n:m关系一样习惯。
现在,给定一个部件ID列表,我想检查是否有一个具有这些部分的部分,但没有更多!
因此,如果例如段2具有部分1和3并且段5具有部分1,3和7,当我请求&#34时;给出部分1和3的部分"我只想要返回段2,而不是两者都返回。
Segments Parts
------------------------ ------------------------
| ID | Name | | ID | Name |
------------------------ ------------------------
| 1 | Segment 1 | | 1 | Part 1 |
| 2 | Segment 2 | | 2 | Part 2 |
| 3 | Segment 3 | | 3 | Part 3 |
| 4 | Segment 4 | | 4 | Part 4 |
| 5 | Segment 5 | | 5 | Part 5 |
------------------------ | 6 | Part 6 |
| 7 | Part 7 |
------------------------
segments_parts
------------------------
| segment_id | part_id |
------------------------
| 1 | 1 |
| 1 | 4 |
| 2 | 1 |
| 2 | 3 |
| 3 | 2 |
| 3 | 4 |
| 4 | 2 |
| 4 | 3 |
| 5 | 1 |
| 5 | 3 |
| 5 | 7 |
------------------------
给定输入1,3我想要返回段ID 2(因为它是具有这两个部分id的段,没有别的。注意段5也有部分1和3,但也有部分7因此应该不予退还!)
给定输入1,3,7我想要返回段ID 5。
给定输入1,6我不想返回任何内容,因为没有包含这两部分的段。
答案 0 :(得分:1)
这是set-within-sets查询。我想使用group by
和having
来解决这些问题。假设没有重复:
select sp.segment_id
from segments_parts sp
group by sp.segment_id
having <list size> = sum(sp.parts_id in (<your list here>)) and
<list size> = count(*);
如果你有重复项,那么:
select sp.segment_id
from segments_parts sp
group by sp.segment_id
having <list size> = count(distinct case when parts_id in (<your list here> then parts_id end) and
<list size> = count(distinct parts_id);
您需要在having
子句中添加列表的长度。