Mysql 如何在不了解列的情况下创建透视表

Mysql 如何在不了解列的情况下创建透视表,mysql,sql,postgresql,pivot,Mysql,Sql,Postgresql,Pivot,我已经阅读了stackoverflow上关于如何创建透视表的大部分文章,但是所有的文章都展示了关于列的先验知识的示例。如果不知道列将是什么,如何构造查询。以下是一些示例数据: id column value Row 1 age 13 1 2 height 55 1 3 fav number NULL 1 4 sibling

我已经阅读了stackoverflow上关于如何创建透视表的大部分文章,但是所有的文章都展示了关于列的先验知识的示例。如果不知道列将是什么,如何构造查询。以下是一些示例数据:

id       column       value       Row
1        age          13          1
2        height       55          1
3        fav number   NULL        1
4        siblings     4           1
5        age          55          2
6        height       54          2
7        fav number   12          2
我正在寻找以下输出:

row        age       height        fav number       siblings
1          13        55            NULL             4
2          55        54            12               NULL

正如您所看到的,没有第2行缺少兄弟条目。查询时列名未知。您将如何进行此查询。

我看不出有任何方法可以只编写一些奇特的SELECT查询来获得所需的内容。你需要做一些预处理


您必须从某种程序、应用程序、脚本等执行此MySQL查询。不确定语言是什么,但以下是我在PHP中要做的:

/* $data is where our data is going to be stored in our desired format */
$data = array();
/* $columns is a list of all column names */
$columns = array();
/* $rows is a list of all row names (probably '1', '2', etc) */
$rows = array();

$result = mysql_query('SELECT column, value, row FROM TableName');
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
  /* if this row isn't in $data yet, add it */
  if (!array_key_exists($row['row'], $data) {
    $data[$row['row']] = array();
  }

  /* if this column isn't in $columns yet, add it */
  if (!in_array($row['column'], $columns)) {
    array_push($columns, $row['column']);
  }

  /* if this row isn't in $rows yet, add it */
  if (!in_array($row['row'], $rows)) {
    array_push($rows, $row['row']);
  }

  /* set the actual value in our multi-dimensional array $data */
  $data[$row['row']][$row['column']] = $row['value'];
}
/* free the result (php specific thing) */
mysql_free_result($result);

/* if we didn't set anything (row, column) pairs, set it to null in $data */
foreach ($rows as $r) {
  foreach ($columns as $c) {
    if (!array_key_exists($c, $data[$r])) {
      $data[$r][$c] = null;
    }
  }
}
这将把所有数据转换成PHP数组中所需的格式


例如,在上面提供的示例数据上运行此算法后,您将能够执行以下操作:

echo $data['2']['age']; // $data['row']['column']
输出55


或者,如果您的数据库没有被实时更新(您有一堆数据希望一次而不是连续地重新格式化),您可以扩展上面的脚本,使其也有一些“createtable”、“INSERT-in”查询,这些查询基本上以您所要找的格式重新创建表


此外,如果您实时接收数据,您仍然可以编写上述脚本,但您只需要在处理原始表时从原始表中删除行,然后在将数据放入原始表时运行脚本即可。

我怀疑您是否可以在MySQL或PostgreSQL中按预期执行此操作,然而,在数据非常自由的情况下,我使用了另一种方法。我们的用例是“菜单项传递回应用程序的属性”,当然我们在查询中不知道这些。但不能创建简单的透视表

不能这样做的原因是PostgreSQL要求提前定义返回的元组结构。并非所有数据库都这样做(例如,Informix允许不同的行具有不同的结构!),但大多数数据库都这样做

我们的方法仅适用于PostgreSQL。然而,也许通过一些调整,你可以在某处找到一个MySQL等价物。我们所做的基本上是在您的版本中:

select row, array_agg("column" || '=' || "value") from sample_data group by row;
这将产生如下输出:

1 {"age=3","height=55",null,"siblings=4"}
2 {"age=55","height=54","favorite_number=12"}
您甚至可以通过以下方式消除空值:

select row, array_agg("column" || '=' || "value")
 WHERE value is not null
 GROUP BY row;
然后你会得到这样的结果:

1 {"age=3","height=55","siblings=4"}
2 {"age=55","height=54","favorite_number=12"}

但我不知道如何在MySQL中实现同样的功能。

您打算如何使用具有未知列的结果集?亲爱的上帝,这是一个。。。元数据库???(邪恶音乐:ta taaaaaaa)@Adrian我喜欢元数据库:)@njk那么,看看这是喜剧还是恐怖故事:@Adrian读起来很有趣。我的道歉,因为我是认真的。