通过时间戳将MySQL表重组为多行

时间:2010-05-10 23:51:54

标签: mysql group-by

确定MySQL奇才:

我有一个来自多个探针的位置数据表,其定义如下:

+----------+----------+------+-----+---------+-------+
| Field    | Type     | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| time     | datetime | NO   |     | NULL    |       | 
| probe_id | char(3)  | NO   |     | NULL    |       | 
| position | float    | NO   |     | NULL    |       | 
+----------+----------+------+-----+---------+-------+

一个简单的选择输出如下:

+---------------------+----------+----------+
| time                | probe_id | position |
+---------------------+----------+----------+
| 2010-05-05 14:16:42 | 00A      |   0.0045 | 
| 2010-05-05 14:16:42 | 00B      |   0.0005 | 
| 2010-05-05 14:16:42 | 00C      |    0.002 | 
| 2010-05-05 14:16:42 | 01A      |        0 | 
| 2010-05-05 14:16:42 | 01B      |    0.001 | 
| 2010-05-05 14:16:42 | 01C      |   0.0025 | 
| 2010-05-05 14:16:43 | 00A      |   0.0045 | 
| 2010-05-05 14:16:43 | 00B      |   0.0005 | 
| 2010-05-05 14:16:43 | 00C      |    0.002 | 
| 2010-05-05 14:16:43 | 01A      |        0 | 
|          .          |  .       |      .   |
|          .          |  .       |      .   |
|          .          |  .       |      .   |
+---------------------+----------+----------+

但是,我想输出这样的内容:

+---------------------+--------+--------+-------+-----+-------+--------+
| time                | 00A    | 00B    | 00C   | 01A | 01B   | 01C    |
+---------------------+--------+--------+-------+-----+-------+--------+
| 2010-05-05 14:16:42 | 0.0045 | 0.0005 | 0.002 | 0   | 0.001 | 0.0025 |
| 2010-05-05 14:16:43 | 0.0045 | 0.0005 | 0.002 | 0   | 0.001 | 0.0025 |
| 2010-05-05 14:16:44 | 0.0045 | 0.0005 | 0.002 | 0   | 0.001 | 0.0025 |
| 2010-05-05 14:16:45 | 0.0045 | 0.0005 | 0.002 | 0   | 0.001 | 0.0025 |
| 2010-05-05 14:16:46 | 0.0045 | 0.0005 | 0.002 | 0   | 0.001 | 0.0025 |
| 2010-05-05 14:16:47 | 0.0045 | 0.0005 | 0.002 | 0   | 0.001 | 0.0025 |
|          .          |    .   |    .   |   .   | .   |   .   |    .   |
|          .          |    .   |    .   |   .   | .   |   .   |    .   |
|          .          |    .   |    .   |   .   | .   |   .   |    .   |
+---------------------+--------+--------+-------+-----+-------+--------+

理想情况下,根据表中的数据动态生成不同的探测位置列。这是可能的,还是我把头发拉出来了?

我用GROUP_CONCAT尝试了GROUP BY时间粗略地获取了数据,但我无法将该输出分成probe_id列。

mysql> SELECT time, GROUP_CONCAT(probe_id), GROUP_CONCAT(position) FROM MG41 GROUP BY time LIMIT 10;
+---------------------+-------------------------+------------------------------------+
| time                | GROUP_CONCAT(probe_id)  | GROUP_CONCAT(position)             |
+---------------------+-------------------------+------------------------------------+
| 2010-05-05 14:16:42 | 00A,00B,00C,01A,01B,01C | 0.0045,0.0005,0.002,0,0.001,0.0025 | 
| 2010-05-05 14:16:43 | 01C,01B,01A,00C,00B,00A | 0.0025,0.001,0,0.002,0.0005,0.0045 | 
| 2010-05-05 14:16:44 | 01C,01B,01A,00C,00B,00A | 0.0025,0.001,0,0.002,0.0005,0.0045 | 
| 2010-05-05 14:16:45 | 01C,01B,01A,00C,00B,00A | 0.0025,0.001,0,0.002,0.0005,0.0045 | 
| 2010-05-05 14:16:46 | 01C,01B,01A,00C,00B,00A | 0.0025,0.001,0,0.002,0.0005,0.0045 | 
| 2010-05-05 14:16:47 | 01C,01B,01A,00C,00B,00A | 0.0025,0.001,0,0.002,0.0005,0.0045 | 
| 2010-05-05 14:16:48 | 01C,01B,01A,00C,00B,00A | 0.0025,0.001,0,0.002,0.0005,0.0045 | 
| 2010-05-05 14:16:49 | 01C,01B,01A,00C,00B,00A | 0.0025,0.001,0,0.002,0.0005,0.0045 | 
| 2010-05-05 14:16:50 | 01C,01B,01A,00C,00B,00A | 0.0025,0.001,0,0.002,0.0005,0.0045 | 
| 2010-05-05 14:16:51 | 01C,01B,01A,00C,00B,00A | 0.0025,0.001,0,0.002,0.0005,0.0045 | 
+---------------------+-------------------------+------------------------------------+

2 个答案:

答案 0 :(得分:2)

SELECT
    time,
    SUM(CASE WHEN probe_id = '00A' THEN position ELSE 0 END) `00A`,
    SUM(CASE WHEN probe_id = '00B' THEN position ELSE 0 END) `00B`,
    SUM(CASE WHEN probe_id = '00C' THEN position ELSE 0 END) `00C`,
    SUM(CASE WHEN probe_id = '01A' THEN position ELSE 0 END) `01A`,
    SUM(CASE WHEN probe_id = '01B' THEN position ELSE 0 END) `01B`,
    SUM(CASE WHEN probe_id = '01C' THEN position ELSE 0 END) `01C`
FROM MG41
GROUP BY time LIMIT 10;

答案 1 :(得分:1)

要拥有动态行数,您需要动态生成的查询。 (如果您事先知道probe_ids,那么您可以使用静态查询。)

一般表格将是

    SELECT time, P00A, P00B, ... P03B, etc..
    FROM 
       (SELECT time FROM MG41 GROUP BY time) allTimes
    INNER JOIN 
        (SELECT time, position AS P00A from MG41 WHERE probe_id='00A') pt00A 
        ON pt00A.time=allTimes.time   
   INNER JOIN 
        (SELECT time, position AS P00B from MG41 WHERE probe_id='00B') pt00B 
        ON pt00B.time=allTimes.time

etc...

然后为所有不同的探测器构建INNER JOIN和SELECTed行。