如何创建另一个动态(元)查询生成的查询的视图

问题描述 投票:0回答:1

如何将下面的查询转换为临时视图? 我尝试过的所有操作都会返回生成的查询的文本(第二个引用的代码块)。 “一切”包括...

  • 将第一个查询包装在另一个查询中
    SELECT * FROM...
  • 执行
    CREATE TEMP VIEW
    作为第一个查询,或作为第一个查询的选择,或仅作为没有任何选择的文本
  • A
    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);
postgresql dynamic pivot-table
1个回答
0
投票

将它们包装在

procedure
中,您可以动态地
execute
该查询的输出。
您的客户可以在会话开始时
call
此过程一次,让它设置/交换
view
,从那时起他们将在静态名称
my_view
:
下找到新结构 db<>fiddle 的演示

--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
© www.soinside.com 2019 - 2024. All rights reserved.