簡體   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