我有一个数据表,我想导出到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,但无法获得结果..
在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来分组,所以不是最好的想法或者所有这些...
答案 0 :(得分:8)
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
答案 1 :(得分:4)
只需加入桌子!
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_1值都存在input_2的值。如果不是这种情况,请使用LEFT JOIN
或CROSS JOIN
等