简体   繁体   English

如何在不知道列的情况下进行数据透视表

[英]How to do pivot table without knowledge of columns

I have read most of the posts on stackoverflow on how to do a pivot table but all of the posts show examples with prior knowledge of the columns. 我已经阅读了关于如何进行数据透视表的stackoverflow上的大多数帖子,但所有帖子都显示了具有列的先验知识的示例。 How do you construct a query if you have no knowledge of what the columns will be. 如果您不知道列将是什么,如何构造查询。 here is some sample data: 这是一些示例数据:

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

I am looking for this output: 我正在寻找这个输出:

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

As you can see there is no row 2 is missing an entry for siblings. 正如您所看到的,没有第2行缺少兄弟姐妹的条目。 The column names are unknown at the time of the query. 查询时列名称未知。 How would you make this query. 你会如何进行这个查询。

I don't see any way you can just write some fancy SELECT query to get what you want. 我没有看到任何方法你可以写一些花哨的SELECT查询来获得你想要的。 You're going to have to do some pre-processing. 你将不得不做一些预处理。


You have to be executing this MySQL query from some sort of program, application, script, etc. Not sure what the language is, but here's what I would do in PHP: 您必须从某种程序,应用程序,脚本等执行此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;
    }
  }
}

This will put all the data into a format you want in an array in PHP. 这将把所有数据放入PHP中的数组中所需的格式。


For example, after running this algorithm on the sample data you provided above, you would be able to do: 例如,在您上面提供的示例数据上运行此算法后,您将能够:

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

Which would output 55. 哪个会输出55。


OR if your database isn't being updated in real time (you have a bunch of data that you'd like to reformat once, rather than continuously), you could extend the script above to also have some "CREATE TABLE", "INSERT INTO" queries that basically recreate the table in the format you're looking for. 或者,如果您的数据库没有实时更新(您有一堆数据需要重新格式化一次,而不是连续更新),您可以将上面的脚本扩展为还有一些“CREATE TABLE”,“INSERT” INTO“查询基本上以您正在寻找的格式重新创建表格。

Furthermore, if you ARE receiving data in realtime, you can still write the script described above, but you'd just want to remove the rows from the original table as you processed them, and then just run the script whenever data is being put into the original table. 此外,如果您实时接收数据,您仍然可以编写上述脚本,但是您只需要在处理原始表时从原始表中删除这些行,然后只需在数据输入时运行该脚本原表。

I doubt that you can do this in MySQL or PostgreSQL as you expect to, however there is an alternative which I have used where data is very free-form. 我怀疑你可以像你期望的那样在MySQL或PostgreSQL中做到这一点,但是我已经使用了一种替代方法,其中数据是非常自由的形式。 Our use case is "attributes that the menu items pass back to the application" and of course we have no knowledge of these in the query. 我们的用例是“菜单项传递回应用程序的属性”,当然我们在查询中不了解这些属性。 But you can't create a simple pivot table. 但是你无法创建一个简单的数据透视表。

The reason you can't is that PostgreSQL requires that the tuple structure returned to be defined in advance. 你不能的原因是PostgreSQL要求返回的元组结构提前定义。 Not all db's do this (Informix for example, allows different rows to have different structures!) but most do. 并非所有db都这样做(例如,Informix允许不同的行具有不同的结构!)但大多数都这样做。

Our approach is PostgreSQL-only. 我们的方法仅限PostgreSQL。 However, maybe with some tweaking you can find a MySQL equivalent somewhere. 但是,也许通过一些调整,您可以找到某个地方的MySQL等价物。 What we did would basically be in your version: 我们所做的基本上就是你的版本:

select row, array_agg("column" || '=' || "value") from sample_data group by row;

This produces output like: 这会产生如下输出:

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

You can even get rid of the NULLS by: 您甚至可以通过以下方式摆脱NULLS:

select row, array_agg("column" || '=' || "value")
 WHERE value is not null
 GROUP BY row;

Then you get something like: 然后你会得到类似的东西:

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

I don't know how to do the same in MySQL though. 我不知道如何在MySQL中做同样的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM