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