我有一张要导出到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_timestamp值对data_value进行分组,以便对时间戳进行分组,并且每个data_id的每个data_value都显示在列中,而不是行中。
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
但这不是我想要的,因为只要一个data_id没有值,现在就有NULL值。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个ID进行分组,因此也不是将所有这些都视为OR的最佳主意。
PIVOTing既不容易(也不是很好)。我更喜欢使用CASE:
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中使用:
IF
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:
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