如何在一列中生成多个总和?
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的值都应该算正常。
如何在查询中执行此操作?有人可以帮助我吗?
试试下面的逻辑-
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.
您可以在下面看到我的查询,结果如下:
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的值都应该算正常。
如何在查询中执行此操作?有人可以帮助我吗?
试试下面的逻辑-
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.