使用GROUP BY的mysql pivot查询结果

使用GROUP BY的mysql pivot查询结果,mysql,csv,pivot,Mysql,Csv,Pivot,我有一个要导出到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

我有一个要导出到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_值进行分组,这样时间戳就被分组了,每个data_id的每个data_值都显示在一列中,而不是一行中

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
但这并不是我想要的,因为现在只要一个数据id没有值,就会有空值。GROUP BY似乎也对数据值进行分组,这不是我想要的

有什么建议吗

编辑:

我已经尝试在外部查询中使用WHERE d.input_1 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
添加d.input_1不为NULL的位置将删除输入_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要分组,因此不是最好的想法,也不是所有的想法。

只需将表格本身加入即可

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;

请注意,此查询假定每个输入值都存在输入值2。如果不是这种情况,使用
左连接
交叉连接

透视
进行旋转既不容易(也不好)。我更喜欢使用
案例

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
但是
如果
也在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级
连接:

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

为什么不在外部查询中添加一个
WHERE
子句来过滤
NULL
值呢?@Michael,我确实有一个WHERE d.input_1 not NULL,它对第一个id很有效,但对第二个id却不有效。我对它进行了编辑以说明..那么为什么不添加
和d.input_2不为空呢
?我尝试过,但那根本不会返回任何结果,因为当input_1和input_2都为空时不会出现这种情况。一个总是有一个值,当另一个为空时…因此,您可以使用
IF
来选择非空的值。我不希望使用20级连接(这让我感到紧张),但您的大小写(和IF)实际上是我很久以前使用的(后来忘记了)。吸引我的是SUM的使用,它实际上并不是所有分组结果的总和。非常感谢@crawf:你可以通过20级连接进行测试。它可能更快:)经过几次测试,它比IF解决方案稍微快一点。我很惊讶,我不认为参加那么多次会更快。再次感谢@crawf:欢迎,使用大表进行测试,例如100K行和更多行(并保留较快的一行)。如果有机会,你可以用它来处理这么多的数据。如果我能接受两个答案,我会的!这就是我投票支持它的原因。问题是我有20个数据ID要加入。对于yor解决方案,我需要有20个不同的连接,这是我不喜欢的(并且不确定这将如何降低性能)。我不是故意不接受,这对于一个包含2个数据ID的表来说是完美的!