MySQL результаты запроса сводки с GROUP BY
У меня есть таблица данных, которые я хочу экспортировать в CSV. В идеале я хотел бы переключать строки и столбцы так, чтобы данные группировались немного лучше.
Чтобы объяснить далее, в настоящее время база данных выглядит следующим образом.
data_id data_timestamp data_value
--------------------------------------------
1 2011-07-07 00:01:00 0.400
1 2011-07-07 00:02:00 0.500
1 2011-07-07 00:03:00 0.600
1 2011-07-07 00:04:00 0.700
2 2011-07-07 00:01:00 0.100
2 2011-07-07 00:02:00 0.200
2 2011-07-07 00:03:00 0.250
2 2011-07-07 00:04:00 2.300
Что бы я хотел сделать, сгруппируйте data_value по значению data_timestamp, чтобы отметки времени были сгруппированы, и каждое data_value для каждого data_id отображается в столбце, а не в строке.
data_timestamp input_1 input_2
--------------------------------------------
2011-07-07 00:01:00 0.400 0.100
2011-07-07 00:02:00 0.500 0.200
2011-07-07 00:03:00 0.600 0.250
2011-07-07 00:04:00 0.700 2.300
Ниже приведен запрос, который я использую...
SELECT d.data_timestamp, d.input_1, d.input_2
FROM (
SELECT data_timestamp,
IF(data_id=1,data_value,NULL) AS 'input_1',
IF(data_id=2,data_value,NULL) AS 'input_2' FROM data
) AS d ORDER BY data_timestamp ASC
Но это не совсем то, что я хочу, так как теперь есть значения NULL, когда один data_id не имеет значения. Кажется, что GROUP BY также группирует data_value, а это не то, что я хочу.
Какие-либо предложения?
РЕДАКТИРОВАТЬ:
Я уже пытался использовать WHERE d.input_1 IS NOT NULL во внешнем запросе, но не могу получить результаты..
До ГДЕ...
data_timestamp input_1 input_2
--------------------------------------------
2011-07-07 00:01:00 0.400 NULL
2011-07-07 00:01:00 NULL 0.100
2011-07-07 00:02:00 0.500 NULL
2011-07-07 00:02:00 NULL 0.200
2011-07-07 00:03:00 0.600 NULL
2011-07-07 00:03:00 NULL 0.250
2011-07-07 00:04:00 0.700 NULL
2011-07-07 00:04:00 NULL 2.300
Добавление WHERE d.input_1 IS NOT NULL приведет к удалению значений input_2.
data_timestamp input_1 input_2
--------------------------------------------
2011-07-07 00:01:00 0.400 NULL
2011-07-07 00:02:00 0.500 NULL
2011-07-07 00:03:00 0.600 NULL
2011-07-07 00:04:00 0.700 NULL
Кроме того, на самом деле, у меня есть около 20 идентификаторов, чтобы сгруппировать их, так что не будет лучшей идеей для ИЛИ или для всех них..
2 ответа
PIVOT
Это не легко (и не приятно). Я предпочитаю использовать CASE
:
SELECT d.data_timestamp
, SUM( CASE WHEN data_id = 1 THEN data_value ELSE 0 END ) AS 'input_1'
, SUM( CASE WHEN data_id = 2 THEN data_value ELSE 0 END ) AS 'input_2'
...
, SUM( CASE WHEN data_id = 20 THEN data_value ELSE 0 END ) AS 'input_20'
FROM data
GROUP BY data_timestamp
ORDER BY data_timestamp ASC
но IF
работает и в MySQL:
SELECT d.data_timestamp
, SUM( IF(data_id = 1, data_value, 0) ) AS 'input_1'
, SUM( IF(data_id = 2, data_value, 0) ) AS 'input_2'
...
, SUM( IF(data_id = 20, data_value, 0) ) AS 'input_20'
FROM data
GROUP BY data_timestamp
ORDER BY data_timestamp ASC
Кроме того, вы можете использовать 20-уровневый JOIN
:
SELECT d.data_timestamp
, d01.data_value AS 'input_1'
, d02.data_value AS 'input_2'
...
, d20.data_value AS 'input_20'
FROM
( SELECT DISTINCT d.data_timestamp
FROM data
) AS d
LEFT JOIN data AS d01
ON d01.data_timestamp = d.data_timestamp
AND d01.data_id = 1
LEFT JOIN data AS d02
ON d02.data_timestamp = d.data_timestamp
AND d02.data_id = 2
... --- 20 JOINs
LEFT JOIN data AS d20
ON d20.data_timestamp = d.data_timestamp
AND d20.data_id = 20
ORDER BY d.data_timestamp ASC
Просто присоедините стол к себе!
SELECT dt1.data_timestamp, dt1.input_1, dt2.input_2
FROM data_timestamp dt1
JOIN data_timestamp dt2
on dt1.data_timestamp = dt2.data_timestamp
and dt2.input_1 is null
WHERE dt1.input_2 is null;
Обратите внимание, что этот запрос предполагает, что значение input_2 присутствует для каждого значения input_1. Если это не тот случай, используйте LEFT JOIN
или же CROSS JOIN
так далее