苦苦于理解复杂的连接

时间:2011-12-28 20:11:46

标签: mysql sql join

以下是我的查询

SELECT cover.id              AS cID,
       cover.title           AS cTitle,
       cover.slug            AS cSlug,
       cover.image           AS cImage,
       cover.timestamp       AS cTimestamp,
       category.name         AS catName,
       category.slug         AS catSlug,
       GROUP_CONCAT(tag.tag) AS tags
FROM   cover
       JOIN category
         ON cover.category_id = category.id
       LEFT OUTER JOIN cover_tag
         ON cover_tag.cover_id = cover.id
       LEFT OUTER JOIN tag
         ON tag.id = cover_tag.tag_id
GROUP  BY cover.title
LIMIT  0, 30  

这将返回每个封面的所有封面和所有标签。现在,如果我只想返回带有'cars'标签的行,但仍然会返回封面上的所有标签,该怎么办?

我正在尝试在Google上寻求帮助,但不知道我在搜索什么。

3 个答案:

答案 0 :(得分:2)

如果我明白你在问什么,

SELECT cover.id              AS cID,
       cover.title           AS cTitle,
       cover.slug            AS cSlug,
       cover.image           AS cImage,
       cover.timestamp       AS cTimestamp,
       category.name         AS catName,
       category.slug         AS catSlug,
       GROUP_CONCAT(tag.tag) AS tags
FROM   cover
       JOIN category
         ON cover.category_id = category.id
       JOIN cover_tag
         ON cover_tag.cover_id = cover.id
       LEFT OUTER JOIN tag
         ON tag.id = cover_tag.tag_id
       JOIN tag T2
         ON T2.id = cover_tag.tag_id AND T2.tag = 'cars'
GROUP  BY cover.title
LIMIT  0, 30  

最后一次加入应该确保cover_tag有一个名为'cars'的标签。

编辑嗯,更好的解释......一张图片?他们说,保存了超过9000个单词。带有“照片,汽车,伟大”标签的封面的匹配结构将是:

                     [cover] ---- [category]
                        |
                        |
                        |
[tag:photos] ----/ [cover_tag] ---- [T2:cars]
[tag:cars]   ---/
[tag:great]  --/

对于标签设置为“小丑,鞋子,气球,kids_love_it”的封面,T2不匹配,因此cover_tag不匹配,因此cover不匹配。

答案 1 :(得分:1)

添加此功能是否有效?

HAVING INSTR(CONCAT(',',GROUP_CONCAT(tag.tag),',') , ',Car,') > 0 

答案 2 :(得分:0)

将其视为2查询问题,从而产生单独的数据集。然后我们找到这两组的交集。

你已经获得了第一套:“(所有)所有标签都包含”。第二组“覆盖标记值'汽车'”将与添加WHERE子句的原始查询相同,过滤标记值“cars”。

现在,将两者结合起来。该技术强调:

+第二个查询进入“where exists”(或“不存在”)

+第二个查询过滤特定值

+“中心”表的每个实例的主键是该过滤器的一部分

SELECT c1.id AS cID, c1.title AS cTitle, c1.slug AS cSlug, c1.image AS cImage, c1.timestamp AS cTimestamp, cat1.name AS catName, cat1.slug AS catSlug,       GROUP_CONCAT( t1.tag ) AS tags
FROM cover c1
JOIN category cat1 ON c1.category_id = cat1.id
LEFT OUTER JOIN cover_tag ct1 ON ct1.cover_id = c1.id
LEFT OUTER JOIN tag t1 ON t1.id = ct1.tag_id
WHERE
    EXISTS (
        SELECT *    -- what we select is irrelevant. We only care that the row exists
        FROM cover c2
        JOIN category cat2 ON c2.category_id = cat2.id
        LEFT OUTER JOIN cover_tag ct2 ON ct2.cover_id = c2.id
        LEFT OUTER JOIN tag t2 ON t2.id = ct2.tag_id
        WHERE
            t2.value = "cars"
            and c1.id = c2.id
    )
GROUP BY c1.title
LIMIT 0 , 30