如何在一列中生成多个总和?

How to generate multiple sums within a column?

您可以在下面看到我的查询,结果如下:

select t.actual_date, 
   t.id_key, 
   t.attendance_status, 
   t.money_step, 
   sum(t.money_step) over (partition by t.id_key order by t.actual_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)as accumulated
from example t
order by t.id_key, t.actual_date

查询结果

我希望 "accumulated" 列为每个 id_key 添加 "money_step" 的值。如果 id_key 是 Id 的第二次“15”,则计数器应从头开始累加。对于 ID_KEY = 1,它应该如下所示:

累计:

Row 1:20
Row 2: 80
Row 3: 100
Row 4: 120

对于 ID_KEY = 2 应该是这样的:

Row 1: accumulated = 30; attendance_status = 7
Row 2: accumulated = 130; attendance_status = 15
Row 3: accumulated = 30; attendance_status = 15
Row 4: accumulated = 60; attendance_status = 15

15 级总是有最新的日期。从 15 级的第二个日期开始,每个 id 的总和应该重新开始。所有小于15的值都应该算正常。

如何在查询中执行此操作?有人可以帮助我吗?

试试下面的逻辑-

DEMO HERE

SELECT *,
SUM(A.money_step) over (
    partition by A.id_key, A.P 
    ORDER BY A.actual_date 
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)as accumulated
FROM
(
    SELECT A.*,
    (
        SELECT CASE WHEN COUNT(*) >= 2 THEN 2 ELSE 1 END
        FROM your_table B 
        WHERE B.id_key = A.id_key
        AND B.actual_date <= A.actual_date
        AND attendance_status = 15
    ) P
    FROM your_table A
)A
ORDER BY A.id_key,A.actual_date

这是未经测试的,因为我没有转录图像,但是,我认为这会起作用。如果没有,那么消耗品样本数据必须在这里:

WITH CTE AS
    (SELECT t.actual_date,
            t.id_key,
            t.attendance_status,
            t.money_step,
            ROW_NUMBER() OVER (PARTITION BY t.id_key,
                                            CASE attendance_status WHEN 15 THEN 1 ELSE 0 END
                               ORDER BY t.actual_date) AS RN
     FROM example t)
SELECT C.actual_date,
       C.id_key,
       C.attendance_status,
       C.money_step,
       SUM(t.money_step) OVER (PARTITION BY t.id_key, CASE WHEN RN > 1 THEN 1 ELSE 0 END
                               ORDER BY t.actual_date
                               ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS accumulated
FROM CTE C;

我强烈建议您仅使用 window 函数来执行此操作。其实很简单:

SELECT t.*,
       SUM(t.money_step) OVER (PARTITION BY id_key, grp ORDER BY actual_date) as accumulated
FROM (SELECT t.*,
             SUM(CASE WHEN seqnum = 2 AND attendance_status = 15 THEN 1 ELSE 0 END) OVER
                 (PARTITION BY id_key ORDER BY actual_date) as grp
      FROM (SELECT t.*,
                   ROW_NUMBER() OVER (PARTITION BY id_key, attendance_status ORDER BY actual_date) as seqnum
            FROM t
           ) t
     ) t
ORDER BY t.id_key, t.actual_date;

Here 是一个 db<>fiddle.