如何将下面的查询转换为临时视图? 我尝试过的所有操作都会返回生成的查询的文本(第二个引用的代码块)。 “一切”包括...
SELECT * FROM...
CREATE TEMP VIEW
作为第一个查询,或作为第一个查询的选择,或仅作为没有任何选择的文本CREATE FUNCTION
第一个查询,然后是函数的 CREATE TEMP VIEW
我无法真正将其包装到 plpgsql 函数中,因为它是对包含任意数量行的表的交叉表的动态查询,该表交叉表到任意数量的列。 因此,我无法定义
plpgsql
函数的返回类型。
下面的代码直接取自 Erwin Brandstetter 对 Transpose a table by conversion columns to rows 的回答。
第一个查询:
SELECT 'SELECT * FROM crosstab( $ct$SELECT u.attnum, t.rn, u.val FROM (SELECT row_number() OVER () AS rn, * FROM ' || attrelid::regclass || ') t , unnest(ARRAY[' || string_agg(quote_ident(attname) || '::text', ',') || ']) WITH ORDINALITY u(val, attnum) ORDER BY 1, 2$ct$ ) t (attnum bigint, ' || (SELECT string_agg('r'|| rn ||' text', ', ') FROM (SELECT row_number() OVER () AS rn FROM tbl) t) || ')' AS sql FROM pg_attribute WHERE attrelid = 'tbl'::regclass AND attnum > 0 AND NOT attisdropped GROUP BY attrelid;
使用 attnum 而不是实际的列名进行操作。更简单、更快。将结果再次连接到 pg_attribute 或集成列 类似于第 9.3 页示例中的名称 [of Erwin Brandstetter 对通过将列转换为行来转置表格的回答]。
生成以下形式的查询:
第二个查询:
SELECT * FROM crosstab( $ct$ SELECT u.attnum, t.rn, u.val FROM (SELECT row_number() OVER () AS rn, * FROM tbl) t , unnest(ARRAY[sl_no::text,username::text,designation::text,salary::text]) WITH ORDINALITY u(val, attnum) ORDER BY 1, 2$ct$ ) t (attnum bigint, r1 text, r2 text, r3 text, r4 text);
procedure
中,您可以动态地 execute
该查询的输出。call
此过程一次,让它设置/交换 view
,从那时起他们将在静态名称 my_view
:--create extension crosstab;
create table tbl(a text, b int);
insert into tbl select 1,1;
create procedure set_up_my_view() as $a$
DECLARE dynsql text;
BEGIN
SELECT INTO dynsql
'DROP VIEW IF EXISTS my_view;
CREATE TEMP VIEW my_view AS
SELECT * FROM crosstab(
$ct$SELECT u.attnum, t.rn, u.val
FROM (SELECT row_number() OVER () AS rn, * FROM '
|| attrelid::regclass || ') t
, unnest(ARRAY[' || string_agg(quote_ident(attname)
|| '::text', ',') || '])
WITH ORDINALITY u(val, attnum)
ORDER BY 1, 2$ct$
) t (attnum bigint, '
|| (SELECT string_agg('r'|| rn ||' text', ', ')
FROM (SELECT row_number() OVER () AS rn FROM tbl) t)
|| ')' AS sql
FROM pg_attribute
WHERE attrelid = 'tbl'::regclass
AND attnum > 0
AND NOT attisdropped
GROUP BY attrelid;
EXECUTE dynsql;
END $a$ language plpgsql;
客户端会话示例:
call set_up_my_view();
select * from my_view;
attnum | r1 |
---|---|
1 | 1 |
2 | 1 |
添加一些内容来显示结构变化:
insert into tbl values (7,7);
call set_up_my_view();
select * from my_view;
attnum | r1 | r2 |
---|---|---|
1 | 1 | 7 |
2 | 1 | 7 |
insert into tbl values (9,9);
call set_up_my_view();
select * from my_view;
attnum | r1 | r2 | r3 |
---|---|---|---|
1 | 1 | 7 | 9 |
2 | 1 | 7 | 9 |