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_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分组,这不是我想要的。
有什么build议么?
编辑:
我已经试过在外部查询中使用WHERE d.input_1 IS NOT 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个id,所以也不是最好的想法。
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
只要join表格就可以了!
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
等