SQL - 聚合数据行

时间:2016-06-22 13:33:33

标签: sql postgresql pivot aggregate-functions

我有一个关于旅程的中间步骤的下表,我希望聚合每天每人一行。中间步骤可能涉及乘客离开并进入站点的各个门,这些门将始终一个接一个地跟随。

因此,在下表中,乘客1234在时间1071在站5598处退出,然后在时间1073处在站796处进入(时间被编码为数值)。然后,他们在时间1086在635站出口,然后在时间1088在站5148进入。这个特定的乘客在他们的旅程中有2个中间腿。对于乘客5678,他们只有一条中间腿。

表格如下:

 ID    day    station    time    type   
1234    133    5598      1071    exit
1234    133    796       1073    entry
1234    133    635       1086    exit 
1234    133    5148      1088    entry 
5678    133    8909      1305    exit 
5678    133    5158      1306   entry 

我希望看起来像这样:

ID    day    stage1_exittime    stage1_exitstation    stage2_entrytime    stage2_entrystation    stage2_exittime    stage2_exitstation    stage3_entrytime    stage3_entrystation
1234  133    1071               5598                  1073                796                     1086                635                 1088                 5148
5678  133    1305               8909                  1306                5158                    0                    0                   0                    0

我尝试过first_value,over和partition by,但无法让它工作。关键是我需要确保在上表中的阶段2_exit和阶段3中没有填充仅有1个中间支路的行程。

应该注意的是,乘客在行程中最多可能有5条中间腿(如示例所示,不是3条)。

1 个答案:

答案 0 :(得分:0)

这可以帮助您获得结果。

row_number命令条目和退出,您只需要按类型获取正确的row_number以确定顺序。

SELECT  "ID",
        "day",
        MAX(CASE WHEN Rn = 1 AND "type" = 'exit' THEN "time" END) AS stage1_exittime, 
        MAX(CASE WHEN Rn = 1 AND "type" = 'exit' THEN "station" END) AS stage1_exitstation,
        MAX(CASE WHEN Rn = 1 AND "type" = 'entry' THEN "time" END) AS stage2_entrytime,
        MAX(CASE WHEN Rn = 1 AND "type" = 'entry' THEN "station" END) AS stage2_entrystation,
        MAX(CASE WHEN Rn = 2 AND "type" = 'exit' THEN "time" END) AS stage2_exittime,
        MAX(CASE WHEN Rn = 2 AND "type" = 'exit' THEN "station" END) AS stage2_exitstation,
        MAX(CASE WHEN Rn = 2 AND "type" = 'entry' THEN "time" END) AS stage3_entrytime,
        MAX(CASE WHEN Rn = 2 AND "type" = 'entry' THEN "station" END) AS stage3_entrystation
FROM    (   
            SELECT  "ID",
                    "station",
                    "time",
                    "type",
                    "day",
                    ROW_NUMBER() OVER (PARTITION BY "ID", "day", "type" ORDER BY "time") AS Rn
            FROM    myTable 
        ) mt
GROUP BY "ID",
        "day"