我正在使用标记系统来处理图像存储库。我有3个表:images
,tags
和tapMap
。
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。
答案 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