У меня есть три таблицы, которые я хочу запросить в 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
Но результат столбца Col3
null
Любая помощь высоко ценится! Большое спасибо!
Запрос недействителен, и MySQL должен вызвать исключение. Вместо этого он молча применяет ANY_VALUE
к вашим выражениям, произвольно выбирая либо искомое значение, либо нулевое значение. Попробуйте SET sql_mode = 'ONLY_FULL_GROUP_BY'
, чтобы MySQL больше не разрешал такие недопустимые запросы.
Вам нужно использовать функцию агрегации, чтобы вы не получали случайные данные строки в 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
@Ajax: Пожалуйста, посмотрите соединения в запросе Ника. Соединения с разделителями-запятыми, которые вы использовали в исходном запросе, стали излишними в 1992 году. Интересно, как вам вообще пришла в голову идея их использовать. Не надо. Если вы пользуетесь книгой или учебным пособием или посещаете занятия, в которых вас этому учат, прекратите это.
Это вариант ответа Ника. От 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
Жаль, что MySQL позволяет использовать предложение GROUP BY без функций агрегирования. Лучше сделать вид, что это не так.