在一对多的情况下选择行

时间:2009-04-28 07:49:52

标签: mysql select

我认为我坚持这种特殊情况:

以下是我的表格:

item_table:
id |项目
1:A
2:B
3:C

attr_table:
attr | item_id
1:1
1:2
2:1
2:3
3:2
3:3
我想知道技术上是否可以检索与attr = 1和3相关的任何项目。答案应该只是'B'。 同样,如果我请求与attr = 1和2相关联的项目,我应该只获得'A'。

问题是attr_table可能有很多行,我希望只做一个查询。

这个问题听起来很简单,我因为无法回答而感到非常沮丧。

我希望聪明的人可以帮我一把......

5 个答案:

答案 0 :(得分:2)

该示例是为SQLServer编写的,但查询应该在mysql中工作。

Key是HAVING COUNT语句等于必须匹配的属性数量。如果属性应为(1,2,5),则必须将计数更改为3。

DECLARE @item_table TABLE (ID INTEGER PRIMARY KEY, Item CHAR(1))
DECLARE @attr_table TABLE (Attr INTEGER, Item_ID INTEGER)

INSERT INTO @item_table VALUES (1, 'A')
INSERT INTO @item_table VALUES (2, 'B')
INSERT INTO @item_table VALUES (3, 'C')

INSERT INTO @attr_table VALUES (1, 1)
INSERT INTO @attr_table VALUES (1, 2)
INSERT INTO @attr_table VALUES (2, 1)
INSERT INTO @attr_table VALUES (2, 3)
INSERT INTO @attr_table VALUES (3, 2)
INSERT INTO @attr_table VALUES (3, 3)


SELECT Item
FROM @item_table i
     INNER JOIN @attr_table a ON a.Item_ID = i.ID
WHERE a.Attr IN (1, 3)
GROUP BY Item
HAVING COUNT(a.Attr) = 2

答案 1 :(得分:1)

   SELECT * From attr_table a, item_table i
   where a.item_id = i.id
   and a.attr = 1
   and a.item_id  in (select item_id from attr_table where  attr = 3);  

作业是否为B项返回一行。

答案 2 :(得分:1)

select * from item_table a 
where exists ( select * from attr_table b 
               where b.item_id = a.id and b.attr = 1)
and exists ( select * from attr_table c 
             where c.item_id = a.id and c.attr = 3);

请注意,此查询确切地说明了您的规范所说的内容:从item_table获取所有行,其中至少有一行来自attr_table,该行具有该行的ID且指定的第一个attr 其中至少有一行来自attr_table,其中包含该行的id和指定的第二个attr。

答案 3 :(得分:0)

select distinct item_table.item from item_table, attr_table
where item_table.id = attr_table.item_id
and attr_table.attr = 1 and attr_table.attr = 3;

基本上它会与您期望的匹配完成并最终会产生大量行 - 但是然后distinct关键字会运行,因此您将获得最小的唯一行集作为最终结果。

(从某种程度上说,我希望它更有效率,但不要费心去弥补匹配行的完整列表。)

答案 4 :(得分:0)

这可能为时已晚,但我建议使用一些类似的连接:

select i.item, b.item_id, c.item_id 
from item_table i 
join attr_table b on i.id=b.item_id and b.item_id=1
join attr_table c on i.id=c.item_id and c.item_id=2

我就是这样做的。