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;
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
2条答案
按热度按时间yeotifhr1#
这可以使用筛选聚合来完成:
Online example
mzaanser2#
要做到这一点非常困难。
请注意,您必须在程序中将查询(结果类型)的结尾放在一起。如果它是psql,那么它将看起来像这样:
在你尝试理解上面的代码之前,你应该阅读下面关于
crosstab
函数的文档:https://www.postgresql.org/docs/11/tablefunc.html(或来自相应PG版本的文档)你可能会注意到第一个版本中的
coalesce(a.sum,0)
而不是a.sum
。在大多数情况下,使用coalesce更好,但在问题中,表中有一些n
-s,它们可能意味着NULL
,没有coalesce
,你也可以使用它们(很明显)。