Oracle SQL 按具有不同 ID 的多维数据集分组

Oracle SQL group by cube with distinct ID

示例数据(完整的table有更多列和数百万行):

invoice_number |year            |department      |euros
-------------------------------------------------------------
1234           |2010            |1               | 200
1234           |2011            |1               | 200
1234           |2011            |2               | 200           
4567           |2010            |1               | 450
4567           |2010            |2               | 450
4567           |2010            |3               | 450

我的Objective:

我想以各种可能的组合对每年和每个部门的欧元求和。

结果应该如何显示:

year             |department         |euros
--------------------------------------------
2010             |1                  |650
2010             |2                  |450
2010             |3                  |450
2010             |(null)             |650
2011             |1                  |200
2011             |2                  |200
(null)           |1                  |650
(null)           |2                  |650
(null)           |3                  |450
(null)           |(null)             |650

我的查询:

select      year
,           department
,           sum(euros)
from        table1
group by    cube    (
                    year
            ,       department
                    )

问题:

一个发票号可以出现在多个类别中。例如,一张发票可以包含 2010 年和 2011 年的项目。当我想显示每年的数据时,这没有问题。但是,当我想要所有年份的总计时,欧元将被计算两次,每年一次。我想要 'group by cube' 的功能,但我只想对不同的发票编号求和以进行聚合。

问题table:

year             |department         |euros
--------------------------------------------
2010             |1                  |650
2010             |2                  |450
2010             |3                  |450
2010             |(null)             |1550
2011             |1                  |200
2011             |2                  |200
(null)           |1                  |850
(null)           |2                  |650
(null)           |3                  |450
(null)           |(null)             |1950

是否可以如我所愿?到目前为止,我的搜索没有结果。我已经创建了一个 SQL Fiddle,我希望它有效

select year
      ,department
      ,case when GROUPING_id(year,department) in (3) then sum(dist_euro) else sum(euros) end sums
      ,decode(GROUPING_id(year,department),0,'NO GROUP',1,'DEPARTMENT IS NULL',2,'YEAR IS NULL',3,'TOTAL OVER ALL YEARS') info
      from (
select      year
            ,           department
            ,           euros
            ,case when  row_number() over(partition by year order by year) = 1 then euros else  0 end dist_euro
from table1)
group by    cube    (
                    year
            ,       department
                    )
        order by GROUPING_id(year,department)

[删除了之前的 "solution"]

新尝试:这是一个非常丑陋的解决方案,但它似乎有效,即使两张发票的金额相同。有两次 table 访问,您应该检查性能是否符合 table.

SQL> with table1_cubed as
  2  ( select year
  3         , department
  4         , grouping_id(year,department) gid
  5      from table1
  6     group by cube(year,department)
  7  )
  8  , join_distinct_invoices as
  9  ( select distinct x.*
 10         , r.invoice_number
 11         , r.euros
 12      from table1_cubed x
 13           inner join table1 r on (nvl(x.year,r.year) = r.year and nvl(x.department,r.department) = r.department)
 14  )
 15  select year
 16       , department
 17       , sum(euros)
 18    from join_distinct_invoices
 19   group by year
 20       , department
 21       , gid
 22   order by year
 23       , department
 24  /

      YEAR DEPARTMENT           SUM(EUROS)
---------- -------------------- ----------
      2010 1                           650
      2010 2                           450
      2010 3                           450
      2010                             650
      2011 1                           200
      2011 2                           200
      2011                             200
           1                           650
           2                           650
           3                           450
                                       650

11 rows selected.