У меня эти три таблицы:
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' |
id | owner_id | tag_id | value_id | ----------------------------------- 1 | 1 | 1 | 1 | 2 | 1 | 2 | 1 | 3 | 1 | 3 | 1 |
Таким образом, пользователи могут отправлять значения и вводить любое количество тегов freetext для привязки к этому значению. Мне нужно хранить теги как принадлежащие определенному пользователю, и мне нужно уметь подсчитывать, сколько раз они использовали каждый тег.
Я хочу выполнить запрос, который получает строки из 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;
Вот окончательное решение в моем случае. Сильно основывается на ответе Гордона Линоффа.
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
Предложение WHERE
во втором JOIN
может быть изменено для получения всех значений для данного пользователя.