crosstab() 期望其输入查询(第一个参数)中的以下列,按以下顺序:
-
row_name
- (可选)
extra 列
-
category(匹配第二个交叉表参数中的值)
-
value
您没有row_name。使用窗口函数 dense_rank() 添加代理 row_name。
您的问题留有解释的余地。让我们添加示例行进行演示:
INSERT INTO facts (eff_date, update_date, symbol_id, data_type_id, source_id)
VALUES
(now(), now(), 1, 5, 'foo')
, (now(), now(), 1, 6, 'foo')
, (now(), now(), 1, 7, 'foo')
, (now(), now(), 1, 6, 'bar')
, (now(), now(), 1, 7, 'bar')
, (now(), now(), 1, 23, 'bar')
, (now(), now(), 1, 5, 'baz')
, (now(), now(), 1, 23, 'baz'); -- only two rows for 'baz'
解释#1:前N个值
您想为每个不同的 (source_id, symbol_id, eff_date) 列出 data_type_id 的前 N 个值(如果有更多,则为最小)。
为此,还需要合成category,可以合成row_number()。生成crosstab() 输入的基本查询:
SELECT dense_rank() OVER (ORDER BY eff_date, symbol_id, source_id)::int AS row_name
, eff_date, symbol_id, source_id -- extra columns
, row_number() OVER (PARTITION BY eff_date, symbol_id, source_id
ORDER BY data_type_id)::int AS category
, data_type_id AS value
FROM facts
ORDER BY row_name, category;
交叉表查询:
SELECT *
FROM crosstab(
'SELECT dense_rank() OVER (ORDER BY eff_date, symbol_id, source_id)::int AS row_name
, eff_date, symbol_id, source_id -- extra columns
, row_number() OVER (PARTITION BY eff_date, symbol_id, source_id
ORDER BY data_type_id)::int AS category
, data_type_id AS value
FROM facts
ORDER BY row_name, category'
, 'VALUES (1), (2), (3)'
) AS (row_name int, eff_date timestamp, symbol_id int, source_id char(3)
, datatype_1 int, datatype_2 int, datatype_3 int);
结果:
行名 |有效日期 |符号 ID | source_id |数据类型_1 |数据类型_2 |数据类型_3
--------: | :----------------| --------: | :-------- | ---------: | ---------: | ---------:
1 | 2017-04-10 ... | 1 |酒吧 | 6 | 7 | 23
2 | 2017-04-10 ... | 1 |巴兹 | 5 | 23 | 空
3 | 2017-04-10 ... | 1 |富 | 5 | 6 | 7
解释 #2:列名中的实际值
您希望将data_type_id 的实际值附加到列名datatypeValue1, ... DatatypeValueN。其中一项或多项:
SELECT DISTINCT data_type_id FROM facts ORDER BY 1;
5, 6, 7, 23 在示例中。那么实际显示值可以只是boolean(或冗余值?)。基本查询:
SELECT dense_rank() OVER (ORDER BY eff_date, symbol_id, source_id)::int AS row_name
, eff_date, symbol_id, source_id -- extra columns
, data_type_id AS category
, TRUE AS value
FROM facts
ORDER BY row_name, category;
交叉表查询:
SELECT *
FROM crosstab(
'SELECT dense_rank() OVER (ORDER BY eff_date, symbol_id, source_id)::int AS row_name
, eff_date, symbol_id, source_id -- extra columns
, data_type_id AS category
, TRUE AS value
FROM facts
ORDER BY row_name, category'
, 'VALUES (5), (6), (7), (23)' -- actual values
) AS (row_name int, eff_date timestamp, symbol_id int, source_id char(3)
, datatype_5 bool, datatype_6 bool, datatype_7 bool, datatype_23 bool);
结果:
有效日期 |符号 ID | source_id |数据类型_5 |数据类型_6 |数据类型_7 |数据类型_23
:----------------| --------: | :-------- | :--------- | :--------- | :--------- | :----------
2017-04-10 ... | 1 |酒吧 | 空 |吨 |吨 |吨
2017-04-10 ... | 1 |巴兹 |吨 | 空 | 空 |吨
2017-04-10 ... | 1 |富 |吨 |吨 |吨 | 空
dbfiddle here
相关: