如何在红移中加入行并将其转置为列
Posted
技术标签:
【中文标题】如何在红移中加入行并将其转置为列【英文标题】:How to join and transpose row to columns in redshift 【发布时间】:2021-12-09 00:14:15 【问题描述】:我有关注table1
,它的唯一键是type
type age
A 20
B 21
C 22
我有以下结果表。我想加入他们的行列
type score
A 10
A 20
A 30
B 40
B 50
按照转置形式。
type age score score score
A 20 10 20 30
B 21 40 50 na
C 22 na na na
有什么方法可以实现吗?
select *
from table1
left join table2 usint(type)
没有转置行。 如果有人有意见请告诉我 谢谢
【问题讨论】:
Redshift 还是 Postgres?这是两个非常不同的数据库系统。 【参考方案1】:如果您事先不知道每种类型的 score
值的数量,那么您需要一个完整的动态解决方案:
首先我们根据table2
中每个类型的score
值的最大数量创建一个复合类型new_type
。然后使用此复合类型命名最终查询中的列。
CREATE OR REPLACE PROCEDURE new_type() LANGUAGE plpgsql AS
$$
DECLARE
column_txt text ;
BEGIN
SELECT string_agg(' score' || id || ' integer', ',')
INTO column_txt
FROM
( SELECT count(*) AS count
FROM table2
GROUP BY type
ORDER BY 1 DESC
LIMIT 1
) AS a
CROSS JOIN LATERAL generate_series(1, a.count :: integer) AS id ;
EXECUTE 'DROP TYPE IF EXISTS new_type' ;
EXECUTE 'CREATE TYPE new_type AS (' || column_txt || ')' ;
END ;
$$ ;
CALL new_type() ;
那么这个查询将提供预期的结果:
SELECT c.type, c.age
, (jsonb_populate_record( NULL :: new_type
, jsonb_object_agg('score' || c.id, c.score ORDER BY c.score)
)).*
FROM
( SELECT a.type, a.age, b.score, row_number() OVER (PARTITION BY a.type, a.age ORDER BY b.score) AS id
FROM table1 AS a
LEFT JOIN table2 AS b
ON a.type = b.type
) AS c
GROUP BY c.type, c.age
ORDER BY c.type, c.age
测试结果在dbfiddle。
【讨论】:
以上是关于如何在红移中加入行并将其转置为列的主要内容,如果未能解决你的问题,请参考以下文章