我想为POSTGRESQL创建数据透视表或交叉表,如有任何帮助,将不胜感激

44u64gxh  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(2)|浏览(192)

我需要连接下面提到的所有三个表
第一个
这是最后的表应该喜欢后,做交叉表或透视。我尝试了很多方式使用交叉表,但没有工作。谢谢你的帮助
第一个
我已经编辑了上面的问题第二列具有相同的值,而不是唯一的fk_id

yeotifhr

yeotifhr1#

这可以使用筛选聚合来完成:

with data as (
  select me.id, d.code, m."values"
  from model_ex me
    join model m on me.id = m.model_ex_id
    join datatype d on d.id = m.datatype_id
)
select id, 
       max("values") filter (where code = 'Q_1') as q_1,
       max("values") filter (where code = 'Q_2') as q_2,
       max("values") filter (where code = 'Q_3') as q_3,
       max("values") filter (where code = 'Q_4') as q_4,
       max("values") filter (where code = 'Q_5') as q_5,
       max("values") filter (where code = 'Q_6') as q_6,
       max("values") filter (where code = 'Q_7') as q_7,
       max("values") filter (where code = 'Q_8') as q_8,
       max("values") filter (where code = 'Q_9') as q_9,
       max("values") filter (where code = 'Q_10') as q_10
from data       
group by id;

Online example

mzaanser

mzaanser2#

要做到这一点非常困难。

CREATE TABLE datatype(id serial , code text);
INSERT INTO datatype
SELECT  r,format('Q_%s' ,r)
FROM generate_series(1, 10) r;

CREATE TABLE model (id serial , dtid serial , value numeric , exid serial);
INSERT INTO model
SELECT  unnest(ARRAY[1,2 ,3,4 ,5])
       ,unnest(ARRAY[10,8 ,9,1 ,2])
       ,unnest(ARRAY[0.001,0.008,0.1,0.9,0.6])
       ,unnest(ARRAY[1,1 ,4,3 ,2]);

CREATE EXTENSION crosstab;

SELECT  *
FROM crosstab
( $x$
    WITH a AS
    (
        SELECT  exid, dt.id, dt.code ,SUM(value)
        FROM datatype dt
        JOIN model m
        ON m.dtid = dt.id
        GROUP BY 1,2,3
        ORDER BY 1,2
    ) , b AS
    (
        SELECT  exid
        FROM a
        GROUP BY  1
    )
    SELECT  b.exid, dt.code, coalesce(a.sum, 0)
    FROM b
    JOIN datatype dt
    ON true
    LEFT JOIN a
    ON a.exid = b.exid AND a.id = dt.id
    ORDER BY 1, 2$x$
) AS (exid serial , q1 numeric , q2 numeric , q3 numeric , q4 numeric , q5 numeric , q6 numeric , q7 numeric , q8 numeric , q9 numeric , q10 numeric );

请注意,您必须在程序中将查询(结果类型)的结尾放在一起。如果它是psql,那么它将看起来像这样:

SELECT format(
        $omfg$
        SELECT * FROM crosstab(
                $x$WITH a as (
                    select exid,
                        dt.id,
                        dt.code,
                        sum(value)
                    FROM datatype dt
                        JOIN model m ON m.dtid = dt.id
                    group by 1,2,3
                    order by 1,2
                ),
                b as (
                    SELECT exid
                    FROM a
                    GROUP BY 1
                )
                SELECT b.exid,
                    dt.code,
                    coalesce(a.sum, 0)
                FROM b
                    JOIN datatype dt ON true
                    LEFT JOIN a ON a.exid = b.exid
                    AND a.id = dt.id
                order by 1,2 $x$
            ) as (exid serial, %s) $omfg$,
            (
                SELECT array_to_string(array_agg(code || ' numeric'), ', ')
                FROM (
                        SELECT code
                        FROM datatype
                        order by id
                    ) c
            )
    ) \ gexec

在你尝试理解上面的代码之前,你应该阅读下面关于crosstab函数的文档:https://www.postgresql.org/docs/11/tablefunc.html(或来自相应PG版本的文档)
你可能会注意到第一个版本中的coalesce(a.sum,0)而不是a.sum。在大多数情况下,使用coalesce更好,但在问题中,表中有一些n-s,它们可能意味着NULL,没有coalesce,你也可以使用它们(很明显)。

相关问题