多个AND在同一个连接表列上

时间:2012-03-11 13:31:47

标签: mysql sql select left-join

我有三张桌子图片,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

但是没有任何效果它总是会返回零结果,尽管它们存在。

2 个答案:

答案 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确保图像包含所有标记。