连接三个表以获得标签列表
Joining three tables to get a list of tags
我有这三个表:
user_submitted_value
id | owner_id | value |
-----------------------
1 | 1 | 1337 |
2 | 2 | 1337 |
3 | 2 | 1337 |
4 | 1 | 1337 |
标签
id | owner_id | text |
---------------------------
1 | 1 | 'Tag 01' |
2 | 1 | 'Tag 02' |
3 | 1 | 'Tag 03' |
4 | 2 | 'Tag 04' |
user_submitted_value_tag
id | owner_id | tag_id | value_id |
-----------------------------------
1 | 1 | 1 | 1 |
2 | 1 | 2 | 1 |
3 | 1 | 3 | 1 |
基本上,用户可以提交值并输入任意数量的自由文本标签以附加到该值。我需要将标签存储为属于特定用户,并且我需要能够计算他们使用每个标签的次数。
我想要完成的是一个查询,该查询从 user_submitted_value
中获取行并附加标签。例如:
Query value with id 1:
id | owner_id | value | tags |
------------------------------------------------------
1 | 1 | 1337 | "'Tag 01','Tag 02','Tag 03'" |
Query all values belonging to user with id 1:
id | owner_id | value | tags |
------------------------------------------------------
1 | 1 | 1337 | "'Tag 01','Tag 02','Tag 03'" |
4 | 1 | 1337 | "" |
我知道我需要以某种方式加入一次或多次,但我对 SQL 不太满意,无法弄清楚具体方法。
这似乎是一种相当神秘的数据格式 -- 特别是因为 owner_id
在所有表格中重复出现。
无论如何,我认为您想要获取给定用户的值和标签的基本查询如下所示:
select usv.owner_id,
group_concat(distinct usvt.value_id) as values,
group_concat(distinct t.text) as tags
from user_submitted_value usv join
user_submitted_value_tag usvt
on usv.value_id = usvt.value_id and usv.owner_id = usvt.owner_id join
tags t
on usvt.tag_id = t.id and usvt.owner_id = t.owner_id
group by usv_owner_id;
这是我的最终解决方案。很大程度上基于 Gordon Linoff 提交的答案。
SELECT
user_submitted_value.id,
user_submitted_value.creator_id,
user_submitted_value.value,
group_concat(tag.text) AS tags
FROM user_submitted_value
LEFT JOIN user_submitted_value_tag
ON user_submitted_value.id = user_submitted_value_tag.value_id
AND user_submitted_value.creator_id = user_submitted_value_tag.creator_id
LEFT JOIN tag
ON user_submitted_valuetag.tag_id = tag.id
AND user_submitted_value_tag.creator_id = tag.creator_id
WHERE user_submitted_value.id = ?
GROUP BY user_submitted_value.id
可以修改第二个 JOIN
上的 WHERE
子句以获取给定用户的所有值。
我有这三个表:
user_submitted_value
id | owner_id | value | ----------------------- 1 | 1 | 1337 | 2 | 2 | 1337 | 3 | 2 | 1337 | 4 | 1 | 1337 |
标签
id | owner_id | text | --------------------------- 1 | 1 | 'Tag 01' | 2 | 1 | 'Tag 02' | 3 | 1 | 'Tag 03' | 4 | 2 | 'Tag 04' |
user_submitted_value_tag
id | owner_id | tag_id | value_id | ----------------------------------- 1 | 1 | 1 | 1 | 2 | 1 | 2 | 1 | 3 | 1 | 3 | 1 |
基本上,用户可以提交值并输入任意数量的自由文本标签以附加到该值。我需要将标签存储为属于特定用户,并且我需要能够计算他们使用每个标签的次数。
我想要完成的是一个查询,该查询从 user_submitted_value
中获取行并附加标签。例如:
Query value with id 1: id | owner_id | value | tags | ------------------------------------------------------ 1 | 1 | 1337 | "'Tag 01','Tag 02','Tag 03'" | Query all values belonging to user with id 1: id | owner_id | value | tags | ------------------------------------------------------ 1 | 1 | 1337 | "'Tag 01','Tag 02','Tag 03'" | 4 | 1 | 1337 | "" |
我知道我需要以某种方式加入一次或多次,但我对 SQL 不太满意,无法弄清楚具体方法。
这似乎是一种相当神秘的数据格式 -- 特别是因为 owner_id
在所有表格中重复出现。
无论如何,我认为您想要获取给定用户的值和标签的基本查询如下所示:
select usv.owner_id,
group_concat(distinct usvt.value_id) as values,
group_concat(distinct t.text) as tags
from user_submitted_value usv join
user_submitted_value_tag usvt
on usv.value_id = usvt.value_id and usv.owner_id = usvt.owner_id join
tags t
on usvt.tag_id = t.id and usvt.owner_id = t.owner_id
group by usv_owner_id;
这是我的最终解决方案。很大程度上基于 Gordon Linoff 提交的答案。
SELECT
user_submitted_value.id,
user_submitted_value.creator_id,
user_submitted_value.value,
group_concat(tag.text) AS tags
FROM user_submitted_value
LEFT JOIN user_submitted_value_tag
ON user_submitted_value.id = user_submitted_value_tag.value_id
AND user_submitted_value.creator_id = user_submitted_value_tag.creator_id
LEFT JOIN tag
ON user_submitted_valuetag.tag_id = tag.id
AND user_submitted_value_tag.creator_id = tag.creator_id
WHERE user_submitted_value.id = ?
GROUP BY user_submitted_value.id
可以修改第二个 JOIN
上的 WHERE
子句以获取给定用户的所有值。