gpt4 book ai didi

sql - 当我期望多行时,Postgres 中的交叉表函数返回一行输出

转载 作者:行者123 更新时间:2023-11-29 11:28:54 25 4
gpt4 key购买 nike

我目前有一个表格m,格式如下:

id    scenario    period    ct
2 1 1 1
2 1 2 1
2 1 3 1
2 1 4 1
2 2 1 1
2 2 2 1
2 2 3 1
2 2 4 1
2 3 1 1
2 3 2 1
2 3 3 1
2 3 4 1

我想创建下表:

id    scenario    period    1    2    3    4
2 1 1 1
2 1 2 1
2 1 3 1
2 1 4 1
2 2 1 1
2 2 2 1
2 2 3 1
2 2 4 1
2 3 1 1
2 3 2 1
2 3 3 1
2 3 4 1

tablefunc 扩展已经在我的 Postgres 数据库中创建了。我目前正在尝试使用 crosstab() 函数来完成数据透视。但是,我得到的表格如下所示:

id    scenario    period    1    2   3    4 
2 1 1 1 1 1 1

我试过的查询:

SELECT * FROM crosstab(
'SELECT id, scenario, period, ct FROM m
ORDER BY 1',
'SELECT DISTINCT period FROM m
ORDER BY 1')
AS (id, scenario, period, 1, 2, 3, 4);

最佳答案

此查询生成您想要的输出:

SELECT id, scenario, period, p1, p2, p3, p4  -- all except aux column rn
FROM crosstab(
'SELECT row_number() OVER (ORDER BY id, scenario, period)::int AS rn
, id, scenario, period, period, ct
FROM m
ORDER BY 1'
, 'VALUES (1), (2), (3), (4)'
) AS (rn int, id int, scenario int, period int, p1 int, p2 int, p3 int, p4 int);

两个特殊的困难:

  1. row_name 还没有一个唯一的列。我使用 row_number() 生成代理键:rn。我从外部 SELECT 中删除了它以匹配您想要的结果。
    按照您尝试的方式,id 被视为 row_name,所有输入行都聚合到一个输出行中。

  2. 您需要结果中的附加列(scenarioperiod),它们必须位于 row_name 之后和 之前em>类别。您必须列出 period 两次 才能额外获得原始列 - 看起来是多余的。

基础知识:

与此特定案例相关:


通常,您会有这样的查询:

SELECT id, scenario, p1, p2, p3, p4  -- all except aux column rn
FROM crosstab(
'SELECT rank() OVER (ORDER BY id, scenario)::int AS rn
, id, scenario, period, ct
FROM m
ORDER BY 1'
, 'VALUES (1), (2), (3), (4)'
) AS (rn int, id int, scenario int, p1 int, p2 int, p3 int, p4 int);

输出如下:

id   scenario   p1   p2   p3   p4
2 1 1 1 1 1
2 2 1 1 1 1
2 3 1 1 1 1

请注意使用 rank() 而不是 row_number()(id, scenario) 的相同组合组合在一起。
如果计数不全是 1,则结果更有意义。

关于sql - 当我期望多行时,Postgres 中的交叉表函数返回一行输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32917810/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com