【问题标题】:MySQL dynamic cross tabMySQL动态交叉表
【发布时间】:2012-02-17 04:04:28
【问题描述】:

我有一张这样的桌子:

way     stop    time
1       1       00:55
1       2       01:01
1       3       01:07
2       2       01:41
2       3       01:47
2       5       01:49
3       1       04:00
3       2       04:06
3       3       04:12

我想要一张这样的表格:

stop    way_1   way_2   way_3   (way_n)
1       00:55           04:00
2       01:01   01:41   04:06
3       01:07   01:47   04:12
5               01:49

网上有很多关于MySQL交叉表(数据透视表)的解决方案,但是如果我不知道有多少“方式”,我该怎么做呢? 谢谢

【问题讨论】:

    标签: mysql aggregate-functions pivot-table crosstab


    【解决方案1】:

    在准备查询时,列的数量和名称必须固定。这就是 SQL 的工作方式。

    所以你有两种选择来解决这个问题。两种选择都涉及编写应用程序代码:

    (1) 查询way 的不同值,然后编写代码以使用这些来构造数据透视查询,在 SELECT 列表中附加与不同值的数量一样多的列。

    foreach ($pdo->query("SELECT DISTINCT `way` FROM `MyTable`") as $row) {
      $way = (int) $row["way"];
      $way_array[] = "MAX(IF(`way`=$way, `time`)) AS way_$way";
    }
    $pivotsql = "SELECT stop, " . join(", ", $way_array) .
       "FROM `MyTable` GROUP BY `stop`";
    

    现在您可以运行新查询,它的列数与不同 way 值的数量一样多。

    $pivotstmt = $pdo->query($pivotsql);
    

    (2) 按照数据库中的结构逐行查询数据,然后在显示数据之前编写代码以转入列。

    $stoparray = array();
    foreach ($pdo->query("SELECT * FROM `MyTable`") as $row) {
      $stopkey = $row["stop"];
      if (!array_key_exists($stopkey, $stoparray)) {
        $stoparray[$stopkey] = array("stop"=>$stopkey);
      }
      $waykey = "way_" . $row["way"];
      $stoparray[$stopkey][$waykey] = $row["time"];
    }
    

    现在您有一个数组数组,看起来就像您运行了一个透视查询一样,但是您运行的实际 SQL 要简单得多。您将查询结果后处理为一组不同的数组。

    【讨论】:

    猜你喜欢
    • 2012-08-12
    • 2015-02-18
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 2013-09-17
    相关资源
    最近更新 更多