如何从当前行和上一行中获取唯一项的总和,但忽略Oracle SQL中的重复项
如何在Oracle SQL中编写查询以从我拥有的表到我想要的表,如下所示: 我所拥有的:如何从当前行和上一行中获取唯一项的总和,但忽略Oracle SQL中的重复项,sql,database,oracle,Sql,Database,Oracle,如何在Oracle SQL中编写查询以从我拥有的表到我想要的表,如下所示: 我所拥有的: Date Item Units ----------- -------- -------- 05-NOV-2018 A 3 05-NOV-2018 E 4 09-NOV-2018 C 7 16-NOV-2018 B 9 16-NOV-2018
Date Item Units
----------- -------- --------
05-NOV-2018 A 3
05-NOV-2018 E 4
09-NOV-2018 C 7
16-NOV-2018 B 9
16-NOV-2018 D 4
21-NOV-2018 A 5
29-NOV-2018 B 12
29-NOV-2018 C 10
29-NOV-2018 F 6
29-NOV-2018 A 8
我想要的是:
Date Total_Units_Per_Day
----------- --------------------
05-NOV-2018 7
09-NOV-2018 14
16-NOV-2018 27
21-NOV-2018 29
29-NOV-2018 44
如何计算每日总单位列:
Date Item Units Total_Unique_Items_Accumulated_Per_Day Total_Units_Per_Day
----------- -------- -------- ------------------------------- --------------------
05-NOV-2018 A 3 A, E 7
05-NOV-2018 E 4 A, E 7
09-NOV-2018 C 7 A, E, C 14
16-NOV-2018 B 9 A, E, C, B, D 27
16-NOV-2018 D 4 A, E, C, B, D 27
21-NOV-2018 A 5 A, E, C, B, D 29
29-NOV-2018 B 12 A, E, C, B, D, F 44
29-NOV-2018 C 10 A, E, C, B, D, F 44
29-NOV-2018 F 6 A, E, C, B, D, F 44
29-NOV-2018 A 8 A, E, C, B, D, F 44
在2018年11月5日至29日的每一天中,我们将当天和前一天的各项单位相加。但是,如果项目在当天已经存在,则不要考虑前一天的项目单位
例如,2018年11月21日,每天的总单位=29。这是通过将前面所有项目的单位相加完成的,但使用:
从2018年11月21日起,A=5台,而不是从2018年11月5日起,A=3台
这种类型的查询可能吗?任何帮助都将不胜感激:谢谢 这相当复杂。您似乎想要每个项目的最新值 如果您有一个有限的项目列表,那么您可以采用蛮力方法:
select dte,
(lag(case when item = 'A' then units end ignore nulls, 1, 0) over (order by dte) +
lag(case when item = 'B' then units end ignore nulls, 1, 0) over (order by dte) +
lag(case when item = 'C' then units end ignore nulls, 1, 0) over (order by dte) +
lag(case when item = 'D' then units end ignore nulls, 1, 0) over (order by dte) +
lag(case when item = 'E' then units end ignore nulls, 1, 0) over (order by dte) +
lag(case when item = 'F' then units end ignore nulls, 1, 0) over (order by dte)
) as total_units_per_day
from t;
select dte, sum(units) as total_units_per_day
from (select d.dte, t.item, t.units, row_number() over (partition by t.item, d.dte order by t.dte desc) as seqnum
from (select distinct dte from t) d join
t
on t.dte <= d.dte
) td
where seqnum = 1
group by dte
order by dte;
他是一把小提琴
编辑:
以下是一种更一般的方法:
select dte,
(lag(case when item = 'A' then units end ignore nulls, 1, 0) over (order by dte) +
lag(case when item = 'B' then units end ignore nulls, 1, 0) over (order by dte) +
lag(case when item = 'C' then units end ignore nulls, 1, 0) over (order by dte) +
lag(case when item = 'D' then units end ignore nulls, 1, 0) over (order by dte) +
lag(case when item = 'E' then units end ignore nulls, 1, 0) over (order by dte) +
lag(case when item = 'F' then units end ignore nulls, 1, 0) over (order by dte)
) as total_units_per_day
from t;
select dte, sum(units) as total_units_per_day
from (select d.dte, t.item, t.units, row_number() over (partition by t.item, d.dte order by t.dte desc) as seqnum
from (select distinct dte from t) d join
t
on t.dte <= d.dte
) td
where seqnum = 1
group by dte
order by dte;
这将是解决您问题的经典方法: 对每天的单位进行简单求和,然后使用解析函数计算累积和
with tot as (
select trans_date, sum(units) total_unit
from tab
group by trans_date)
select trans_date,
sum(total_unit) over (order by trans_date) total_unit_cum
from tot
order by 1
;
TRANS_DATE TOTAL_UNIT_CUM
------------------- --------------
05.11.2018 00:00:00 7
09.11.2018 00:00:00 14
16.11.2018 00:00:00 27
21.11.2018 00:00:00 32
29.11.2018 00:00:00 68
但这提供了比预期更高的结果。
原因是在一个项目中,您的单位已经累计
因此,在第一步中,清理单元并计算实际的增量值
通过从以前的记录中减去滞后值,默认为零滞后单位,1,0
最后简单地将两个查询组合起来
with clean as (
select
trans_date, item, units units_orig,
units - lag(units,1,0) over (partition by item order by trans_date) units
from tab),
tot as (
select trans_date, sum(units) total_unit
from clean
group by trans_date)
select trans_date,
sum(total_unit) over (order by trans_date) total_unit_cum
from tot
order by 1
;
TRANS_DATE TOTAL_UNIT_CUM
------------------- --------------
05.11.2018 00:00:00 7
09.11.2018 00:00:00 14
16.11.2018 00:00:00 27
21.11.2018 00:00:00 29
29.11.2018 00:00:00 44
这不是一个简短的查询,但很容易理解…@GordonLinoff我的错误,让我来纠正一下,你有多少不同的项目?@GordonLinoff不同项目的数量会增加而不是固定的。顺便说一下,这是我最近遇到的最有趣的问题之一。@doe。我认为这是正确的:A/8、B/12、C/10、D/4、E/4、F/6。这是44,而不是50。一般的方法效果很好!你太棒了,非常感谢!是的,我刚刚意识到,这是我的错!谢谢我删除了戈登在回答时的评论。评论是我认为代码没有考虑F,但是我错过了read,Gordon的代码是正确的