特定值后的行数(有条件)(PostgreSQL)

时间:2017-05-02 11:56:27

标签: sql postgresql

我有一张如下表:

group    sequence   action     value1       value2      value3
1        1          special    1            0           1
1        2          special    1            1           0
1        3          special    1            0           1
1        4          act1       1            0           NULL
1        5          act1       1            0           NULL
1        6          act2       1            0           NULL
1        7          special    1            1           1
1        8          act1       1            1           NULL
1        9          act2       1            1           NULL
1       10          special    1            0           1
1       11          act1       1            0           NULL
2        1          special    1            1           1
2        2          act1       1            1           NULL

我需要计算一般的行动次数:" act1"和" act2"在行动之后发生"特别" (专栏"小组"在这个问题上对我来说并不重要)

所以,最后我想得到这样的表格:

action    value1     value2     value3     count_act1     count_act2 
special   1          0          1          3              1
special   1          1          0          0              0
special   1          1          1          2              1

是否有任何窗口功能,可以帮助我?

1 个答案:

答案 0 :(得分:0)

你可以尝试一下吗(如果它适合你,我们可以继续优化它,但我不确定它是否涵盖你所有的情况)?

SELECT X.*
, COALESCE(RC_ACT1, 0) AS RC_ACT1
, COALESCE(RC_ACT2, 0) AS RC_ACT2
FROM MYTABLE X
LEFT JOIN (
    SELECT A.GROUP_, A.SEQUENCE, COUNT(B.ACT1) AS RC_ACT1  
    FROM (
        SELECT * ,LEAD(ACTION) OVER (PARTITION BY GROUP_ ORDER BY SEQUENCE) AS SUCC1
        FROM MYTABLE 
        WHERE ACTION='special'
        ) A
    LEFT JOIN (SELECT ACTION  AS ACT1, GROUP_, SEQUENCE FROM MYTABLE WHERE ACTION = 'act1') B ON B.GROUP_=A.GROUP_ AND B.SEQUENCE > A.SEQUENCE  
    WHERE SUCC1 IS NULL 
    GROUP BY A.GROUP_, A.SEQUENCE
    ) Y ON X.GROUP_= Y.GROUP_ AND X.SEQUENCE=Y.SEQUENCE
LEFT JOIN (
    SELECT A.GROUP_, A.SEQUENCE, COUNT(B.ACT1) AS RC_ACT2  
    FROM (
        SELECT * ,LEAD(ACTION) OVER (PARTITION BY GROUP_ ORDER BY SEQUENCE) AS SUCC1
        FROM MYTABLE 
        WHERE ACTION='special'
        ) A
    LEFT JOIN (SELECT ACTION  AS ACT1, GROUP_, SEQUENCE FROM MYTABLE WHERE ACTION = 'act2') B ON B.GROUP_=A.GROUP_ AND B.SEQUENCE > A.SEQUENCE  
    WHERE SUCC1 IS NULL 
    GROUP BY A.GROUP_, A.SEQUENCE
    ) Z ON X.GROUP_= Z.GROUP_ AND X.SEQUENCE=Z.SEQUENCE
WHERE X.ACTION = 'special';

输出:

+--------+----------+---------+--------+--------+--------+---------+---------+
| group_ | sequence | action  | value1 | value2 | value3 | rc_act1 | rc_act2 |
+--------+----------+---------+--------+--------+--------+---------+---------+
|      1 |        1 | special |      1 |      0 |      1 |       0 |       0 |
|      1 |        2 | special |      1 |      1 |      0 |       0 |       0 |
|      1 |        3 | special |      1 |      0 |      1 |       2 |       1 |
|      2 |        1 | special |      1 |      1 |      1 |       1 |       0 |
+--------+----------+---------+--------+--------+--------+---------+---------+