简体   繁体   English

无法在Postgres交叉表查询中使用公用表表达式

[英]Unable to use Common Table Expressions in Postgres Crosstab Query

I'm trying to use perform a pivot operation on some data using Postgres' tablefunc extension's CROSSTAB function. 我正在尝试使用Postgres的tablefunc扩展的CROSSTAB函数对某些数据执行数据透视操作。 The data needs to undergo some transformations first, which I perform in some common table expressions . 数据需要首先进行一些转换,我在一些常见的表表达式中执行。

However, it appears CROSSTAB can't see the results of those expressions. 但是,看来CROSSTAB无法看到那些表达式的结果。

For example, this query sourcing data from a temporary table works fine: 例如,从临时表中获取数据的查询工作正常:

CREATE TEMPORARY TABLE
  temporary_table
    (name, category, category_value)
ON COMMIT DROP
AS (
  VALUES
    ('A',  'foo',    1             ),
    ('A',  'bar',    2             ),
    ('B',  'foo',    3             ),
    ('B',  'bar',    4             )
);

SELECT * FROM
  CROSSTAB(
    'SELECT * FROM temporary_table',
    $$
      VALUES
        ('foo'),
        ('bar')
    $$
  ) AS (
    name TEXT,
    foo  INT,
    bar  INT
  );

and, as expected, produces the following output: 并且,如预期的那样,产生以下输出:

name | foo     | bar
text | integer | integer
---- | ------- | -------
A    |       1 |       2
B    |       3 |       4

But the same query, this time using common table expressions doesn't run: 但是相同的查询,这次使用公用表表达式不会运行:

WITH
  common_table
    (name, category, category_value)
AS (
  VALUES
    ('A',  'foo',    1             ),
    ('A',  'bar',    2             ),
    ('B',  'foo',    3             ),
    ('B',  'bar',    4             )
)
SELECT * FROM
  CROSSTAB(
    'SELECT * FROM common_table',
    $$
      VALUES
        ('foo'),
        ('bar')
    $$
  ) AS (
    name TEXT,
    foo  INT,
    bar  INT
  )

and produces the following error: 并产生以下错误:

ERROR:  relation "common_table" does not exist
LINE 1: SELECT * FROM common_table
                      ^
QUERY:  SELECT * FROM common_table

********** Error **********

ERROR: relation "common_table" does not exist
SQL state: 42P01

I take it this means the text query ( SELECT * FROM common_table ) runs in some sort of different context? 我认为这意味着文本查询( SELECT * FROM common_table )在某种不同的上下文中运行?


Note: The tablefunc extension must be enabled for CROSSTAB to be available: 注意:必须启用tablefunc扩展才能使CROSSTAB可用:

CREATE EXTENSION IF NOT EXISTS tablefunc;

All you need to do is move your CTE inside the string as the first argument to crosstab(text, text) function just like you did with the select statement. 您需要做的就是将CTE内的CTE作为crosstab(text, text)函数的第一个参数移动crosstab(text, text)就像使用select语句一样。 It will be parsed and executed properly. 它将被正确解析和执行。 This is because you provide full SQL statement that produces the source set in first argument. 这是因为您提供了在第一个参数中生成源集的完整SQL语句。

You need to double your quotation marks inside the string or use dollar-quoting $$ just like you did with the second argument and I did below: 您需要在字符串内加倍引号或使用引用美元的$$ ,就像您对第二个参数所做的那样,我在下面做了:

SELECT * FROM
  CROSSTAB(
    $$
    WITH common_table(name, category, category_value) AS (
      VALUES
        ('A',  'foo',    1             ),
        ('A',  'bar',    2             ),
        ('B',  'foo',    3             ),
        ('B',  'bar',    4             )
    )
    SELECT * FROM common_table $$,
    $$
      VALUES
        ('foo'),
        ('bar')
    $$
  ) AS (
    name TEXT,
    foo  INT,
    bar  INT
  );

Result 结果

 name | foo | bar
------+-----+-----
 A    |   1 |   2
 B    |   3 |   4

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

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