2016-09-08 43 views
0

我有两个表:段(id,name)和部分(id,name)。这两个关系具有n:m关系,因此段可以有多个部分,一个部分可以属于多个段。MySQL n:m从表1中找到只包含表2中元素的元素

当然,我们有一个链接表segments_parts(segments_id,parts_id)将这两者连接在一起,就像习惯用n:m关系一样。

现在,给出一个零件ID列表,我想检查是否有一个段具有这些部分,但没有更多!

因此,例如,如果段2具有部分1和3,并且段5具有段1,3和7,当我请求“给出段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

添加样品表数据和预期结果。格式化好! – jarlh

回答

1

这是一个集内查询。我喜欢用group byhaving解决这些问题。假设没有重复:

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子句。

+0

哇,完美...只要网站允许,我会给你正确的答案。 :) – Sorcy

+0

啊,我说的太快了......显然它不像我期望的那样工作。我实际上将不得不按照jarl的要求添加一些示例数据,以使我的案例更清晰。敬请关注。 – Sorcy

+0

@Sorcy。 。 。我试图使用一个快捷方式。你可以通过放入列表的长度来修正'having'子句。 –

相关问题