繁体   English   中英

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

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

我正在尝试使用Postgres的tablefunc扩展的CROSSTAB函数对某些数据执行数据透视操作。 数据需要首先进行一些转换,我在一些常见的表表达式中执行。

但是,看来CROSSTAB无法看到那些表达式的结果。

例如,从临时表中获取数据的查询工作正常:

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
  );

并且,如预期的那样,产生以下输出:

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

但是相同的查询,这次使用公用表表达式不会运行:

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
  )

并产生以下错误:

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

我认为这意味着文本查询( SELECT * FROM common_table )在某种不同的上下文中运行?


注意:必须启用tablefunc扩展才能使CROSSTAB可用:

CREATE EXTENSION IF NOT EXISTS tablefunc;

您需要做的就是将CTE内的CTE作为crosstab(text, text)函数的第一个参数移动crosstab(text, text)就像使用select语句一样。 它将被正确解析和执行。 这是因为您提供了在第一个参数中生成源集的完整SQL语句。

您需要在字符串内加倍引号或使用引用美元的$$ ,就像您对第二个参数所做的那样,我在下面做了:

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
  );

结果

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

暂无
暂无

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

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