Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

выборка из 3 таблиц с объединением данных

#sql #выборка


Добрый вечер,
имеется проблема, которую никак не могу решить.
Существует 3 таблицы:


tm_posts - данные о постах и страницах
tm_attributes - данные о тегах и категориях
tm_relationships - связи 1 и 2 таблицы


Пример структуры:

tm_posts:      

id | name | text
-------------------
1  | kols | <ТЕКСТ>
2  | ando | <ТЕКСТ>
3  | krot | <ТЕКСТ>

tm_attributes:    

id | sign | attr_name
-------------------
1  | tag  | учебник
2  | tag  | дождь
3  | cat  | личное
4  | cat  | опыт

tm_relationships:  

id | id_attr | id_post
-------------------
1  |    1    | 2
2  |    2    | 2
3  |    3    | 2
4  |    4    | 2


Мне нужно получить такой результат по нику ando:

id | name |  text   |      tags     |    category   |
-----------------------------------------------------
2  | ando | <ТЕКСТ> | учебник,дождь |  личное,опыт  |


Т.е. берутся данные из таблицы tm_posts по нику ando, ищется связка тегов и категорий
по id поста в таблице tm_relationships. После чего получаем данные из таблицы tm_attributes.
Эти данные сливаем в строку.

Вот что получилось сделать:

SELECT t1.*, GROUP_CONCAT(t3.attr_name) As `tags`
FROM tm_posts t1
JOIN tm_relationships t2 ON t1.id = t2.id_post
JOIN tm_attributes t3 ON t3.id = t2.id_attr
WHERE t1.name= 'ando'
AND t3.sign = 'tag'
GROUP BY t1.id


Этот код выводит все, кроме категорий. Как мне сюда добавить еще и категории.

-----------------------------Добавлено:

Необходимо выбрать все записи из БД с категорией "личное", но при этом к каждой записи
нужно приклеить колонку со связкой тегов.

Структура таблиц остается такая же.
Результат должен выдать, примерно такой:

id | name |   text  |      tags       |      category     |
----------------------------------------------------------------------
2  | ando | <ТЕКСТ> | учебник,дождь   |       личное      |
5  | ник  | <ТЕКСТ> | какие-то теги   |       личное      |
6  | ник  | <ТЕКСТ> | какие-то теги   |       личное      |


Т.е. выбрались все записи с тегами, но только с определенной категорией "личное"
    


Ответы

Ответ 1



Думаю можно сделать два join к tm_attributes наподобие SELECT t1.*, GROUP_CONCAT(t3.attr_name) As `tags`,GROUP_CONCAT(t4.attr_name) As `cats` FROM tm_posts t1 JOIN tm_relationships t2 ON t1.id = t2.id_post left JOIN tm_attributes t3 ON t3.id = t2.id_attr and t3.sign = 'tag' left JOIN tm_attributes t4 ON t4.id = t2.id_attr and t4.sign = 'cat' WHERE t1.name= 'ando' GROUP BY t1.id Для выбора только категории личное пришел в голову только такой запрос fiddle: 1) сначала выбираем все Post с категория личное 2) делаем join к категориям select cat_data.*, GROUP_CONCAT(t3.attr_name) As `tags` from (select t1.*,t4.attr_name from tm_attributes t4 join tm_relationships t2 on id_attr=t4.id join tm_posts t1 on id_post=t1.id where t4.sign = 'cat' and t4.attr_name='личное' ) cat_data join tm_relationships t2 on id_post=cat_data.id left JOIN tm_attributes t3 ON t3.id = t2.id_attr and t3.sign = 'tag' group by cat_data.id

Ответ 2



SELECT t1.*, GROUP_CONCAT(if(t3.sign='tag',t3.attr_name,NULL)) As `tags`, GROUP_CONCAT(if(t3.sign='cat',t3.attr_name,NULL)) As `cats` FROM tm_posts t1 JOIN tm_relationships t2 ON t1.id = t2.id_post JOIN tm_attributes t3 ON t3.id = t2.id_attr WHERE t1.name= 'ando' AND t3.sign in('tag','cat') GROUP BY t1.id Условие t3.sign in('tag','cat') можно убрать, если кроме tag и cat нет других видов и не предвидится. И tm_relationships думаю стоит клеить по LEFT JOIN, в случае, если у какой то статьи может не быть ни тегов ни категорий.

Комментариев нет:

Отправить комментарий