鉴于该设置,我想编写一个查询“选择 th.thing 和一个事物具有的所有标签的列表,其中所有标签的列表包含 tag2”。
我的预期结果集是:
东西1 | 标签1,标签2
标签2东西2 | 标签2,标签3
我已经尝试了各种连接和分组方法GROUP_CONCAT()
,但我似乎无法得到任何工作。
如何使用 1 个查询从数据库中提取我想要的结果集?
鉴于该设置,我想编写一个查询“选择 th.thing 和一个事物具有的所有标签的列表,其中所有标签的列表包含 tag2”。
我的预期结果集是:
东西1 | 标签1,标签2
标签2东西2 | 标签2,标签3
我已经尝试了各种连接和分组方法GROUP_CONCAT()
,但我似乎无法得到任何工作。
如何使用 1 个查询从数据库中提取我想要的结果集?
有点hacky,因为它使用FIND_IN_SET
,但似乎工作(sqlfiddle)。
如果您的任何标签中有逗号,我不会指望它工作,因为GROUP_CONCAT
似乎没有做任何特别的事情来逃避那个逗号,所以FIND_IN_SET
会认为它是一个分隔符。
SELECT
things.thing,
GROUP_CONCAT(tags.tag) AS tags
FROM things
JOIN relationships
ON things.id = relationships.thing_id
JOIN tags
ON relationships.tag_id = tags.id
GROUP BY things.id
HAVING FIND_IN_SET('tag2', GROUP_CONCAT(tags.tag));
产量:
THING TAGS
thing1 tag2,tag1
thing2 tag2,tag3
另一个版本没有使用半连接也没有 FIND_IND_SET,
只是直接连接
SELECT th.thing, GROUP_CONCAT(ta.tag) as tags
FROM things th
JOIN relationships r
ON th.id = r.thing_id
JOIN tags ta
ON ta.id = r.tag_id
JOIN things th2
ON th.id = th2.id
JOIN relationships r2
ON th2.id = r2.thing_id
JOIN tags ta2
ON ta2.id = r2.tag_id
WHERE ta2.tag = 'tag2'
GROUP BY th.id;
正如 Waleed Khan 建议的那样,不使用FIND_IN_SET
,我准备了一个使用 - 子句的查询WHERE
。这不会在带有逗号的标签上中断,通常......
SELECT th.thing, GROUP_CONCAT(ta.tag) as tags
FROM relationships r
INNER JOIN things th ON th.id = r.thing_id
INNER JOIN tags ta ON ta.id = r.tag_id
WHERE th.id IN (SELECT r2.thing_id
FROM relationships r2
INNER JOIN tags ta2 ON ta2.id = r2.tag_id
WHERE ta2.tag = "tag2")
GROUP BY th.id