Используйте CASE THEN в SQL

У меня есть три таблицы, которые я хочу запросить в MySQL следующим образом:

Примечания к таблице

id  | note
-------------------
1   | note 1
2   | note 2

Табличные индексы

id  | name
-----------
1   | height
2   | weight
3   | other

Сведения о таблице

  note_id    |  indices_id |  value
-------------------------------------
    1        |     1       |   50
    1        |     2       |   60
    1        |     3       |   20
    2        |     1       |   40
    2        |     2       |   10
    2        |     3       |   50

Мне нужно запросить результат следующим образом:

  indices.name    |  note_id = 1 |  note_id = 2
------------------------------------------------
    height        |     50       |   40
    weight        |     60       |   10
    other         |     20       |   50

Я попробовал этот запрос:

SELECT i.name,
(CASE WHEN d.note_id = 1 THEN d.value END) as Col2,
(CASE WHEN d.note_id = 2 THEN d.value END) as Col3
FROM notes n,indices i,detail d
WHERE n.id = d.note_id AND i.id = d.indices_id
GROUP BY i.name

Но результат столбца Col3null
Любая помощь высоко ценится! Большое спасибо!

Жаль, что MySQL позволяет использовать предложение GROUP BY без функций агрегирования. Лучше сделать вид, что это не так.

Strawberry 27.05.2019 10:34

Запрос недействителен, и MySQL должен вызвать исключение. Вместо этого он молча применяет ANY_VALUE к вашим выражениям, произвольно выбирая либо искомое значение, либо нулевое значение. Попробуйте SET sql_mode = 'ONLY_FULL_GROUP_BY', чтобы MySQL больше не разрешал такие недопустимые запросы.

Thorsten Kettner 27.05.2019 10:46
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
2
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам нужно использовать функцию агрегации, чтобы вы не получали случайные данные строки в Col2 и Col3. MAX будет работать, так как будет игнорировать значения NULL, если note_id не совпадает. Кроме того, вы должны использовать явный синтаксис JOIN:

SELECT i.name,
       MAX(CASE WHEN d.note_id = 1 THEN d.value END) as Col2,
       MAX(CASE WHEN d.note_id = 2 THEN d.value END) as Col3
FROM notes n
JOIN detail d ON n.id = d.note_id
JOIN indices i ON i.id = d.indices_id
GROUP BY i.name

Выход:

name    Col2    Col3
height  50      40
other   20      50
weight  60      10

Демо на dbfiddle

@Ajax: Пожалуйста, посмотрите соединения в запросе Ника. Соединения с разделителями-запятыми, которые вы использовали в исходном запросе, стали излишними в 1992 году. Интересно, как вам вообще пришла в голову идея их использовать. Не надо. Если вы пользуетесь книгой или учебным пособием или посещаете занятия, в которых вас этому учат, прекратите это.

Thorsten Kettner 27.05.2019 10:38

Это вариант ответа Ника. От JOIN до nodes лишнее:

SELECT i.name,
       MAX(CASE WHEN d.note_id = 1 THEN d.value END) as Col2,
       MAX(CASE WHEN d.note_id = 2 THEN d.value END) as Col3
FROM detail d JOIN
     indices i
     ON i.id = d.indices_id
GROUP BY i.name

Другие вопросы по теме

Похожие вопросы

Первые 5 строк суммируются по ссылке для каждого типа, все остальные равны 1, сгруппированы по идентификатору команды
Как получить сгенерированный внешний ключ, созданный в MySQL, для использования в функции вставки
Ниже приведен код динамической формы, который может вставлять данные, добавляя несколько входных данных от пользователя в строку, но я хочу, чтобы они были в столбце. Как мне это сделать?
Java Spring Boot + Mysql — возвращает ответ Json (ключ-значение), когда результат запроса mysql не соответствует какой-либо модели, соответствующей какой-либо таблице базы данных
Новичок в MySQL Workbench, в чем смысл подключения?
Случай Mysql Switch, возвращающий неверные результаты
Получение ошибки HTTP 500, даже если учетная запись авторизована
Как получить значение столбца в строке с первым вхождением другого значения в определенный столбец в MySQL?
Проверка скрипта с --login-path в Monit дает ОШИБКУ 1045 (28000)
MySQL и PHP не вставляют строки с пробелами или специальными символами