Postgresql > 交叉表查询 > 需要输入

Postgresql > Crosstab query > Need input

使用 Postgresql 9.4 版本。

我必须准备一份报告来比较 table 环境中的结构,即 QA、UAT、PROD。 我已将所有环境中的 table 结构加载到一个 table 中,并希望使用 SQL 交叉表查询生成报告。

我可以比较列名,但无法扩展到数据类型。

create table test_schema_rpt
(
    env_name    varchar2(100),
    tbl_name    varchar2(100),
    col_nm      varchar2(100),
    data_type   varchar2(100),
    col_len     integer

);

insert into test_schema_rpt values ('PROD','test_tbl','col1','character varying','100');
insert into test_schema_rpt values ('PROD','test_tbl','col2','character varying','200');
insert into test_schema_rpt values ('PROD','test_tbl','col3','character varying','300');
insert into test_schema_rpt values ('PROD','test_tbl','col4','integer',null);
insert into test_schema_rpt values ('UAT','test_tbl','col1','character varying','100');
insert into test_schema_rpt values ('UAT','test_tbl','col2','character varying','300');
insert into test_schema_rpt values ('UAT','test_tbl','col3','character','1');
insert into test_schema_rpt values ('UAT','test_tbl','col4','numeric',null);
insert into test_schema_rpt values ('UAT','test_tbl','col5','text',null);
insert into test_schema_rpt values ('QA','test_tbl','col1','character varying','100');
insert into test_schema_rpt values ('QA','test_tbl','col2','character varying','200');
insert into test_schema_rpt values ('QA','test_tbl','col3','character varying','300');
insert into test_schema_rpt values ('QA','test_tbl','col4','numeric',null);
insert into test_schema_rpt values ('QA','test_tbl','col5','text',null);
insert into test_schema_rpt values ('QA','test_tbl','col6','character varying','500');

使用这个查询

select * from crosstab 
(
    'select tbl_name||''.''||col_nm::text table_nm , env_name, col_nm::text       
            from test_schema_rpt order by 1,2'
    ,'select  distinct env_name from test_schema_rpt order by 1'
)
as tbl
( 
    table_nm  text
    ,"QA" text
    ,"UAT" text
    ,"PROD" text 
);

enter image description here

请查看预期结果集图像

考虑一个多值交叉表,如 Postgres 专家所示, 使用复合类型:

DROP TYPE IF EXISTS i2 CASCADE;
CREATE TYPE i2 AS (typ VARCHAR(100), col INTEGER);

SELECT tbl_name, 
       col_nm,
       (a1).typ AS "QA_Data_Type",  
       (a0).typ AS "PROD_Data_Type",  
       (a2).typ AS "UAT_Data_Type",       
       (a1).col AS "QA_col_len",
       (a0).col AS "PROD_col_len",
       (a2).col AS "UAT_col_len"

FROM   crosstab(
   'SELECT tbl_name || col_nm AS row_name, tbl_name, col_nm, env_name, 
           (data_type, col_len)::i2 AS vals
    FROM   test_schema_rpt
    ORDER  BY tbl_name, col_nm, env_name'
    ,
    'select distinct env_name from test_schema_rpt order by 1'
   ) 
AS tbl (   
    row_name VARCHAR(200),
    tbl_name VARCHAR(100),
    col_nm VARCHAR(100),
    a0 i2, 
    a1 i2, 
    a2 i2
);

DB Fiddle (在顶部按 运行)