将列转换为行并获取最新值

时间:2013-11-18 22:19:41

标签: mysql sql

我想将列转换为行,并显示最新值

以下是我的数据库的示例:

表1:

+----+-----------------+
| id |    location     |
+----+-----------------+
|  1 | 2012/East/A/Flw |
|  2 | 2012/East/A/Lvl |
|  3 | 2012/East/B/Flw |
|  4 | 2012/East/B/Lvl |
+----+-----------------+

表2:

+------------+-------+------------------+
| locationid | value |      tstamp      |
+------------+-------+------------------+
|          1 |    10 | 2013-11-18 10:00 |
|          2 |    21 | 2013-11-18 10:00 |
|          3 |     5 | 2013-11-18 10:00 |
|          4 |    30 | 2013-11-18 10:00 |
|          1 |     5 | 2013-11-19 11:00 |
|          2 |    20 | 2013-11-19 11:00 |
|          3 |    15 | 2013-11-19 11:00 |
|          4 |    28 | 2013-11-19 11:00 |
+------------+-------+------------------+

我希望我能让输出像这样:

+----------+-----+-----+
| location | Flw | Lvl |
+----------+-----+-----+
| East A   |   5 |  20 |
| East B   |  15 |  28 |
+----------+-----+-----+

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

您可以利用动态SQL来实现此目标

SET @sql = NULL;

SELECT GROUP_CONCAT(CONCAT(
         'MAX(CASE WHEN locationid IN(', ids, 
         ') THEN value END) `', col, '`'))
  INTO @sql
  FROM 
(
  SELECT SUBSTRING_INDEX(location, '/', -1) col, GROUP_CONCAT(id) ids
    FROM table1
   GROUP BY SUBSTRING_INDEX(location, '/', -1)
) q;

SET @sql = CONCAT(
   'SELECT CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(location, ''/'', 2), ''/'', -1), '' '',
                  SUBSTRING_INDEX(SUBSTRING_INDEX(location, ''/'', -2), ''/'', 1)) location, ',
   @sql,
   '  FROM table1 l LEFT JOIN
    (
      SELECT t.locationid, t.value
        FROM 
      (
        SELECT locationid, MAX(tstamp) tstamp
          FROM table2
         GROUP BY locationid
      ) q JOIN table2 t 
          ON q.locationid = t.locationid
         AND q.tstamp = t.tstamp
    ) d
        ON l.id = d.locationid
     GROUP BY CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(location, ''/'', 2), ''/'', -1), '' '',
                     SUBSTRING_INDEX(SUBSTRING_INDEX(location, ''/'', -2), ''/'', 1))'
);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

输出:

| LOCATION | FLW | LVL |
|----------|-----|-----|
|   East A |   5 |  20 |
|   East B |  15 |  28 |

这是 SQLFiddle 演示