如何从当前行和上一行中获取唯一项的总和,但忽略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

如何在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     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的代码是正确的