postgresql交叉表简单示例

postgresql交叉表简单示例,postgresql,crosstab,Postgresql,Crosstab,我得到了一个基于键值的表,其中每个键值对被分配给一个由id标识的实体: |_id__|_key_______|_value_| | 123 | FIRSTNAME | John | | 123 | LASTNAME | Doe | 我想把它转换成这样的结构: |_id__|_firstName_|_lastName_| | 123 | John | Doe | 我想可以使用postgres内置的交叉表函数来实现 你能告诉我怎么做并解释它为什么工作吗?首先激活内置t

我得到了一个基于键值的表,其中每个键值对被分配给一个由id标识的实体:

|_id__|_key_______|_value_|
| 123 | FIRSTNAME | John  |
| 123 | LASTNAME  | Doe   |
我想把它转换成这样的结构:

|_id__|_firstName_|_lastName_|
| 123 | John      | Doe      |
我想可以使用postgres内置的交叉表函数来实现


你能告诉我怎么做并解释它为什么工作吗?

首先激活内置tablefunc扩展:

CREATE EXTENSION tablefunc;
然后创建表并添加示例数据:

CREATE TABLE example (
  id int,
  key text,
  value text
);

INSERT INTO example VALUES
  (123, 'firstName', 'John'),
  (123, 'lastName', 'Doe');
现在,让我们准备交叉表状态:

SELECT *
FROM example
ORDER BY id ASC, key ASC;
这里有订单很重要

结果:

|_id__|_key_______|_value_|
| 123 | FIRSTNAME | John  |
| 123 | LASTNAME  | Doe   |
|_id__|_firstName_|_lastName_|
| 123 | John      | Doe      |
|_id__|_firstName_|_lastName_|
| 123 | Doe       | John     |
解决方案 现在,crosstab根据需要创建表:

SELECT *
FROM crosstab(
    'SELECT *
     FROM example
     ORDER BY id ASC, key ASC;'
) AS ct(id INT, firstname TEXT, lastname TEXT);
结果:

|_id__|_key_______|_value_|
| 123 | FIRSTNAME | John  |
| 123 | LASTNAME  | Doe   |
|_id__|_firstName_|_lastName_|
| 123 | John      | Doe      |
|_id__|_firstName_|_lastName_|
| 123 | Doe       | John     |
工作原理1 然而,为了理解它是如何工作的,我发现最简单的方法是通过更改顺序,然后看看会发生什么:

SELECT *
FROM crosstab(
    'SELECT *
     FROM example
     ORDER BY id ASC, key DESC;'
) AS ct(id INT, firstname TEXT, lastname TEXT);
结果:

|_id__|_key_______|_value_|
| 123 | FIRSTNAME | John  |
| 123 | LASTNAME  | Doe   |
|_id__|_firstName_|_lastName_|
| 123 | John      | Doe      |
|_id__|_firstName_|_lastName_|
| 123 | Doe       | John     |
当我们更改键的排序时,crosstab函数会看到按另一个方向排序的键,从而反转生成的列

工作原理2 另一件事帮助我理解了它的工作原理:列定义是关于位置的:

SELECT *
FROM crosstab(
    'SELECT *
     FROM example
     ORDER BY id ASC, key ASC;'
) AS ct(blablafirst INT, blablasecond TEXT, blablathird TEXT);
结果

|_blablafirst__|_blablasecond_|_blablathird_|
| 123          | John         | Doe         |

还可以看到我发现的这个解释:最后一个问题“它是如何工作的2”不应该导致John在“blablasecond”下,因为你使用了键ASC吗?@yshahak是的,对。我已经更新了示例。谢谢。也看看这个例子,它有点不同。