Присоединиться к вложенным отношениям в виде столбцов

#mysql #sql

Вопрос:

Мне нужна помощь с моим SQL. Я пытаюсь получить следующие строки…

ID Отправитель Код 1 Код 1 Балл Код 2 Код 2 Балла
1 Неизвестный Джон AB 80 ба 87
2 Джейн Доу компакт-диск 45 dc 99

Столбцы кода-это самая сложная часть. Это и есть отношения

Разговор -> Сообщения ->> Основные моменты ->>> Коды.

  • Сообщения имеют идентификатор беседы
  • Основные сообщения имеют идентификатор message_id
  • Коды имеют идентификатор highlight_id

В одном разговоре много сообщений, в каждом сообщении много основных моментов, а в любых основных моментах много кодов.

 SELECT  conversations.id,  CONCAT(senders.first_name, ' ', senders.last_name) as 'Sender Name'  conversations.created_at AS 'Start Date', FROM  conversations  LEFT JOIN users AS senders ON sender.id = conversations.participant_1  LEFT JOIN users AS recipient ON recipient.id = conversations.participant_2 GROUP BY  conversations.name  

Я не могу понять, как включить коды в результаты в виде столбцов, которые сопряжены (имя кода 1, оценка кода).

Приведенный выше запрос работает для получения первых нескольких столбцов, но я хотел бы присоединиться к кодам. Любая помощь будет признательна.

Ответ №1:

У меня есть идея, которую можно использовать row_number для создания нескольких столбцов

 SELECT m.highlight_id,  MAX( CASE WHEN RN = 1 THEN m.code_name ELSE '' END ),  MAX( CASE WHEN RN = 1 THEN m.code_score ELSE '' END ),  MAX( CASE WHEN RN = 2 THEN m.code_name ELSE '' END ),  MAX( CASE WHEN RN = 2 THEN m.code_score ELSE '' END ),  MAX( CASE WHEN RN = 3 THEN m.code_name ELSE '' END ),  MAX( CASE WHEN RN = 3 THEN m.code_score ELSE '' END ),  MAX( CASE WHEN RN = 4 THEN m.code_name ELSE '' END ),  MAX( CASE WHEN RN = 4 THEN m.code_score ELSE '' END ),  MAX( CASE WHEN RN = 5 THEN m.code_name ELSE '' END ),  MAX( CASE WHEN RN = 5 THEN m.code_score ELSE '' END ) FROM ( SELECT  b.highlight_id, b.code_name, b.code_score, (CASE WHEN @T = b.highlight_id THEN @RN := @RN   1 ELSE @RN := 1 END ) AS RN, @T := b.highlight_id FROM highlights a  JOIN codes b ON a.highlight_id = b.highlight_id JOIN (SELECT @T := '', @RN := 0) u ORDER BY a.highlight_id, b.code_name ) m GROUP BY m.highlight_id ;  

Если вы используете MySQL 8.0, это проще

 SELECT m.highlight_id,  MAX( CASE WHEN RN = 1 THEN m.code_name ELSE '' END ),  MAX( CASE WHEN RN = 1 THEN m.code_score ELSE '' END ),  MAX( CASE WHEN RN = 2 THEN m.code_name ELSE '' END ),  MAX( CASE WHEN RN = 2 THEN m.code_score ELSE '' END ),  MAX( CASE WHEN RN = 3 THEN m.code_name ELSE '' END ),  MAX( CASE WHEN RN = 3 THEN m.code_score ELSE '' END ),  MAX( CASE WHEN RN = 4 THEN m.code_name ELSE '' END ),  MAX( CASE WHEN RN = 4 THEN m.code_score ELSE '' END ),  MAX( CASE WHEN RN = 5 THEN m.code_name ELSE '' END ),  MAX( CASE WHEN RN = 5 THEN m.code_score ELSE '' END ) FROM ( SELECT b.highlight_id, b.code_name, b.code_score, ROW_NUMBER() OVER(PARTITION BY b.highlight_id ORDER BY b.code_name) RN FROM highlights a  JOIN codes b ON a.highlight_id = b.highlight_id ) m GROUP BY m.highlight_id ;  

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

1. Спасибо. Я собираюсь попробовать это сделать. Мой sql ограничен, как бы я вписал это в свой существующий sql?

2. Это идея с highlights JOIN codes иллюстрацией. Вы можете продолжать JOIN добавлять дополнительные таблицы, JOIN messages ON ... JOIN conversations ON ... LEFT JOIN users ... и GROUP BY/PARTITION часть, вероятно, также нуждается в изменениях в соответствии с вашими требованиями.