我有三张桌子图片,image_tags和标签。图像表包含图像信息,标签包含标签信息,image_tags包含图像和标签之间的关系,关系是多对多的。我想基于AND条件(不是IN)的多个标签过滤图像。
我试过了:
SELECT images.* FROM images
LEFT JOIN image_tags ON image_tags.image_id = images.id
LEFT JOIN tags tag_0 ON image_tags.tag_id = tag_0.id
LEFT JOIN tags tag_1 ON image_tags.tag_id = tag_1.id
WHERE tag_0.tag = "tagme"
AND tag_1.tag = "excellent"
AND images.filesize > 0
GROUP BY images.id
ORDER BY images.posted DESC LIMIT 0, 40
和
SELECT images.* FROM images
LEFT JOIN image_tags ON image_tags.image_id = images.id
LEFT JOIN tags ON image_tags.tag_id = tags.id
WHERE tags.tag = "tagme"
AND tags.tag = "excellent"
AND images.filesize > 0
GROUP BY images.id
ORDER BY images.posted DESC LIMIT 0, 40
但是没有任何效果它总是会返回零结果,尽管它们存在。
答案 0 :(得分:1)
您的第一个查询,即使它使用LEFT
加入,也需要tags
上的“tagme”和“excellent”中的匹配,因为条件位于where子句。将条件移动到ON
子句中,如下所示:
SELECT images.* FROM images
LEFT JOIN image_tags ON image_tags.image_id = images.id
LEFT JOIN tags tag_0 ON image_tags.tag_id = tag_0.id AND tag_0.tag = 'tagme'
LEFT JOIN tags tag_1 ON image_tags.tag_id = tag_1.id AND tag_1.tag = 'excellent'
WHERE images.filesize > 0
GROUP BY images.id
ORDER BY images.posted DESC LIMIT 0, 40
你的第二个问题是关闭 - 它有一个不可能的条件:
WHERE tags.tag = "tagme"
AND tags.tag = "excellent"
tags.tag
不能 “tagme”和“优秀”。
答案 1 :(得分:0)
你的尝试都不够正确,尽管第一个尝试更接近正确的尝试。要按照您尝试过滤代码的方式过滤代码,您需要加入image_tags
两次并加入tags
的两个实例以分隔image_tags
的实例。而且似乎你想做内连接而不是外连接。这里:
SELECT i.*
FROM images i
INNER JOIN image_tags it0 ON it0.image_id = i.id
INNER JOIN tags t0 ON t0.id = it0.tag_id
INNER JOIN image_tags it1 ON it1.image_id = i.id
INNER JOIN tags t1 ON t1.id = it1.tag_id
WHERE i.filesize > 0
AND t0.tag = 'tagme'
AND t1.tag = 'excellent'
ORDER BY i.posted DESC
LIMIT 0, 40
还有另一种方法可以做同样的事情。请尝试以下方法:
SELECT i.*
FROM images i
INNER JOIN image_tags it ON it.image_id = i.id
INNER JOIN tags t ON t.id = it.tag_id
WHERE i.filesize > 0
AND t.tag IN ('tagme', 'excellent')
GROUP BY i.id
HAVING COUNT(DISTINCT i.tag) = 2
ORDER BY i.posted DESC
LIMIT 0, 40
t.tag IN ('tagme', 'excellent')
条件限制允许标记到指定列表,HAVING COUNT(DISTINCT i.tag) = 2
确保图像包含所有标记。