在postgres9.6中创建pivot表

mbjcgjjk  于 2021-07-29  发布在  Java
关注(0)|答案(2)|浏览(319)

我无法使用sql创建所需的输出。我有一个事件表,它保存了每个候选人参加的每个事件的记录,如下所示:

| id | asmnt   | timestamp           | score |
|----|---------|---------------------|-------|
| 1  | pushups | 2020-06-21 12:31:12 | 34    |
| 1  | situps  | 2020-06-21 13:31:12 | 65    |
| 1  | run     | 2020-06-22 12:31:12 | 901   |
| 1  | pullups | 2020-06-21 14:31:12 | 15    |
| 2  | pushups | 2020-06-21 12:31:12 | 13    |
| 2  | situps  | 2020-06-21 13:31:12 | 21    |
| 2  | run     | 2020-06-22 12:31:12 | 1401  |
| 2  | pullups | 2020-06-21 14:31:12 | 3     |
| 2  | pushups | 2020-06-23 12:31:12 | 31    |
| 2  | situps  | 2020-06-23 13:31:12 | 45    |
| 2  | run     | 2020-06-24 12:31:12 | 1101  |
| 2  | pullups | 2020-06-23 14:31:12 | 13    |

我可以从中创建数据透视表吗?我尝试使用交叉表扩展,但由于每个组(按id)的大小不同,因此出现了一个错误(不足为奇)。保留顺序(asmnt)以及按时间戳排序很重要。
这是我想要的输出:

| id | pushups | situps | run | pullups |
|----|---------|--------|-----|---------|
| 1  | 34      | 65     | 901 |   15    |
| 2  | 31      | 45     | 1101|   13    |

以下是我尝试过的sql(asmnt:apfps、apfsu、apf2m或apfpl):

select *
from crosstab('select brandi_id, asmnt_code, score
from event
where left(asmnt_code,3) = ''APF''
order by brandi_id, asmnt_code, event_timestamp') 
    as events(brandi_id INTEGER,APF2M TEXT,APFPL TEXT,APFPS TEXT,APFSU TEXT,score INTEGER);
zz2j4svz

zz2j4svz1#

我知道你想要 score 最新的 asmntid ,在数据透视结果集中。
如果是的话,你可以用 distinct on 要获取每个组的最新记录,然后进行条件聚合以透视:

select
    id,
    max(score) filter(where asmnt = 'pushups') pushups,
    max(score) filter(where asmnt = 'situps') situps,
    max(score) filter(where asmnt = 'run') run,
    max(score) filter(where asmnt = 'pullups') pullups
from (
    select distinct on (id, asmnt) e.*
    from event e
    order by id, asmnt, timestamp desc
) e
group by id
4dc9hkyq

4dc9hkyq2#

使用过滤的聚合通常是最简单的方法:

select id, 
       count(*) filter (were asmnt = 'pushups') as pushups,
       count(*) filter (were asmnt = 'situps') as situps,
       count(*) filter (were asmnt = 'run') as run,
       count(*) filter (were asmnt = 'pullups') as pullups
from event
group by id;

相关问题