postgresql交叉表简单的例子

Gam*_*ing 4 postgresql crosstab

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

|_id__|_key_______|_value_|
| 123 | FIRSTNAME | John  |
| 123 | LASTNAME  | Doe   |
Run Code Online (Sandbox Code Playgroud)

我想将它转换为这样的结构:

|_id__|_firstName_|_lastName_|
| 123 | John      | Doe      |
Run Code Online (Sandbox Code Playgroud)

我想可以使用postgres build in crosstabfunction来做到这一点.

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

Gam*_*ing 10

首先在tablefunc-extension中激活构建:

CREATE EXTENSION tablefunc;
Run Code Online (Sandbox Code Playgroud)

然后创建表并添加样本数据:

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

INSERT INTO example VALUES
  (123, 'firstName', 'John'),
  (123, 'lastName', 'Doe');
Run Code Online (Sandbox Code Playgroud)

现在让我们准备一下这个crosstab声明:

SELECT *
FROM example
ORDER BY id ASC, key ASC;
Run Code Online (Sandbox Code Playgroud)

拥有ORDER BY这里很重要.

结果:

|_id__|_key_______|_value_|
| 123 | FIRSTNAME | John  |
| 123 | LASTNAME  | Doe   |
Run Code Online (Sandbox Code Playgroud)

现在crosstab创建我们想要的表:

SELECT *
FROM crosstab(
    'SELECT *
     FROM example
     ORDER BY id ASC, key ASC;'
) AS ct(id INT, firstname TEXT, lastname TEXT);
Run Code Online (Sandbox Code Playgroud)

结果:

|_id__|_firstName_|_lastName_|
| 123 | John      | Doe      |
Run Code Online (Sandbox Code Playgroud)

它是如何工作的#1

然而,要了解它是如何工作的,我发现最容易改变ORDER BY并看看会发生什么:

SELECT *
FROM crosstab(
    'SELECT *
     FROM example
     ORDER BY id ASC, key DESC;'
) AS ct(id INT, firstname TEXT, lastname TEXT);
Run Code Online (Sandbox Code Playgroud)

结果:

|_id__|_firstName_|_lastName_|
| 123 | Doe       | John     |
Run Code Online (Sandbox Code Playgroud)

当我们更改键的排序时,该crosstab函数会看到按另一个方向排序的键,从而反转生成的列.


工作原理#2

另一件事让我理解它是如何工作的:列定义是关于位置的:

SELECT *
FROM crosstab(
    'SELECT *
     FROM example
     ORDER BY id ASC, key ASC;'
) AS ct(blablafirst INT, blablasecond TEXT, blablathird TEXT);
Run Code Online (Sandbox Code Playgroud)

结果

|_blablafirst__|_blablasecond_|_blablathird_|
| 123          | Doe          | John        |
Run Code Online (Sandbox Code Playgroud)