Результаты запроса сводки MySQL с GROUP BY - PullRequest
1 голос
/ 07 июля 2011

У меня есть таблица данных, которую я хочу экспортировать в 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 не равен NULL во внешнем запросе, но не может получить результаты ..

До WHERE ...

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 ]

8 голосов
/ 07 июля 2011

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
4 голосов
/ 07 июля 2011

Просто присоедините стол к себе!

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 и т. Д.

...