MySQL:如何根据其他行选择行?

时间:2014-04-17 17:04:14

标签: php mysql database select tags

我正在使用标记系统来处理图像存储库。我有3个表:imagestagstapMap

images包含图像信息 tags包含所有标签(每行都是唯一的)
tagMap存储图像和标签之间的关联

tagMap看起来像这样:

id    |   img_ID   |   tag_ID
1           22           51
2           22           55
3           25           55
4           27           56
5           30           70
6           30           71
7           31           70

我想要做的是能够抓取具有多个标签的图像。所以我可以查询类似SELECT img_ID FROM tagMap WHERE tag_ID = 51 AND tag_ID = 55的内容。

问题在于,由于每个关联存储在一个单独的行中,我无法做到。

有什么想法吗?

修改
要清楚,我只想选择包含所有传递标签的图像。所以上面的查询应该只返回img_ID 22。

4 个答案:

答案 0 :(得分:0)

你可以通过两个子查询和两者的INTERSECT来实现这一点。

SELECT img_ID
FROM tagMap
WHERE tag_ID = 51
INTERSECT
SELECT img_ID
FROM tagMap
WHERE tag_ID = 52;

如果你在mysql中做这个,它不支持INTERSECT,这是一种做交叉的方法:

SELECT t3.img_ID from (
  (SELECT img_ID FROM tagMap WHERE tag_ID = 51) AS t1 
  UNION ALL 
  (SELECT img_ID FROM tagMap WHERE tag_ID = 52) AS t2 
) AS t3 GROUP BY img_ID HAVING count(*) >= 2;

答案 1 :(得分:0)

可能是这样的:

SELECT img_ID FROM tagMap t1
WHERE tag_ID = 51
  AND exists (select 1 from tagmap t2 where t2.tag_ID = 52 and t2.img_ID = t1.img_ID)

编辑:另一个选项是

select t1.img_ID 
from (SELECT * FROM tagMap WHERE tag_ID = 51) t1
inner join (SELECT * FROM tagMap WHERE tag_ID = 52) t2 ON t1.img_id =  t2.img_ID

根据您要选择的标签数量和数据量,一个或另一个可能更容易/更快。对于表中的大数据量和要选择的大量标记,两者都不可能很好地扩展(对于每个要包含的附加标记,在两种情况下都需要额外的子选择)

<强>增加: 另一种可能的解决方案:

SELECT Q.img_id FROM (
    SELECT img_ID, count(1) as num
    FROM tagMap t1
    WHERE tag_ID in (51, 52)
    GROUP BY img_id ) Q 
WHERE Q.num = 2

我认为这个可能会做得最好。要添加额外的标记,只需添加到in()条件并增加外部where条件匹配的数字。 E.g。

SELECT Q.img_id FROM (
    SELECT img_ID, count(1) as num
    FROM tagMap t1
    WHERE tag_ID in (51, 52, 59)
    GROUP BY img_id ) Q 
WHERE Q.num = 3

答案 2 :(得分:0)

您可以多次加入同一张桌子:

SELECT i.*
FROM images i
JOIN tagMap tm1
  ON tm1.img_ID = i.img_ID
JOIN tagMap tm2
  ON tm2.img_ID = i.img_ID
WHERE tm1.tag_ID = '51'
  AND tm2.tag_ID = '55'

或者,如果您愿意:

SELECT i.*
FROM images i
JOIN tagMap tm1
  ON tm1.img_ID = i.img_ID AND tm1.tag_ID = '51'
JOIN tagMap tm2
  ON tm2.img_ID = i.img_ID AND tm2.tag_ID = '55'

答案 3 :(得分:-1)

这将返回所有具有多个标签的图像

//assuming you have id in images table and tags table
SELECT images.id 
FROM images
    INNER JOIN tagMap
        ON tagMap.imgId = images.id
    INNER JOIN tags
        ON tags.id = tagMap.tag_ID