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.
示例数据(完整的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.