我正在使用汇总来获取一些聚合,并以表格形式将它们显示给用户。
但是,我想确保在我的汇总中,汇总的行数是相同的,即最大子集的数量。
我认为一个例子让我想要的更清楚,所以我在下面的oracle中设置了一个简单的例子:
create table test (
co_name varchar2(100),
rtype number,
some_count number
) ;
insert all
into test (co_name, rtype, some_count) values ('A', 1, 5)
into test (co_name, rtype, some_count) values ('A', 2, 6)
into test (co_name, rtype, some_count) values ('A', 3, 7)
into test (co_name, rtype, some_count) values ('B', 1, 8)
into test (co_name, rtype, some_count) values ('B', 2, 9)
SELECT * FROM DUAL
;
select * from test;
SELECT
co_name,
rtype,
count(some_count)
FROM test
GROUP BY ROLLUP(co_name, rtype)
这给了我以下结果:
CO_NAME RTYPE SOME_COUNT
A 1 5
A 2 6
A 3 7
A 18
B 1 8
B 2 9
B 17
B 35
你会注意到B当然只有两行用于RTYPE - 1和2 那是因为有0行,其中CO_NAME = B AND RTYPE = 3
有没有办法让汇总在返回的结果数量上保持一致? 我想要的是看到以下内容:
CO_NAME RTYPE SOME_COUNT
A 1 5
A 2 6
A 3 7
A 18
B 1 8
B 2 9
B 3 0
B 17
35
这里的任何建议都会非常有用,因为我希望我的应用程序是愚蠢的,只需将结果制成表格而不必考虑丢失的数据。我想要查询给我所需的一切。
谢谢!
编辑:我是一个涂料......在我上面的例子中,我想保持简单,但却犯了一个错误。而不是RTYPES是一组{1,2,3}可能的值,想象它是一组{'x','y','z'}可能的值......我确实将答案标记为答案,因为它回答了我问的问题,错误在我身上:(答案 0 :(得分:1)
rollup
条款不会填补空白,您必须事先做好:
SQL> with rtypes(col) as(
2 select level
3 from ( select max(count(co_name)) as mx_num
4 from test1
5 group by co_name
6 ) t
7 connect by level <= t.mx_num
8 )
9 select t.co_name
10 , r.col as rtype
11 , sum(nvl(some_count, 0)) as some_count
12 from test1 t
13 partition by (t.co_name)
14 right join rtypes r
15 on (r.col = t.rtype)
16 group by rollup(t.co_name, r.col)
17 ;
结果:
Co_Name rtype Some_Count
--------------------------------------
A 1 5
A 2 6
A 3 7
A 18
B 1 8
B 2 9
B 3 0
B 17
35
WITH
子句中的查询用于从1到3生成RTYPES
(因为它发生了3
是此情况下rtype
的最大数量)。在主查询中我们右外连接我们的
TEST1
表,其中包含使用RTYPES
子句的partition by()
CTE的实际数据。
回答评论:
如果有字符,正如您所说的一个字符值(x
,y
,z
或a
,b
,c
它
并不重要),在RTYPE
列中,我们可以重写CTE(WITH
子句)生成如下字符集:
with rtypes(col) as(
select chr(min_char + level - 1)
from ( select max(ascii(rtype1)) as max_char
, min(ascii(rtype1)) as min_char
from test1
)
connect by min_char + level <= max_char + 1
)
然后最终的查询将是:
with rtypes(col) as(
select chr(min_char + level - 1)
from ( select max(ascii(rtype1)) as max_char
, min(ascii(rtype1)) as min_char
from test1
)
connect by min_char + level <= max_char + 1
)
select t.co_name
, r.col as rtype
, sum(nvl(some_count, 0)) as some_count
from test1 t
partition by (t.co_name)
right join rtypes r
on (r.col = t.rtype1)
group by rollup(t.co_name, r.col)
结果:
Co_Name rtype Some_Count
--------------------------------------
A x 5
A y 6
A z 7
A 18
B x 8
B y 9
B z 0
B 17
35
答案 1 :(得分:0)
好的,这是我能做的最好的事情:)
它会使用您现有的查询,然后是所有不存在的co_name和rtype组合中的联合。
相同数据:
create table test_rollup (
co_name varchar2(100),
rtype number,
some_count number
) ;
insert all
into test_rollup (co_name, rtype, some_count) values ('A', 1, 5)
into test_rollup (co_name, rtype, some_count) values ('A', 2, 6)
into test_rollup (co_name, rtype, some_count) values ('A', 3, 7)
into test_rollup (co_name, rtype, some_count) values ('B', 1, 8)
into test_rollup (co_name, rtype, some_count) values ('B', 2, 9)
SELECT * FROM DUAL
;
select * from test_rollup;
使用WITH
定义co_name
和rtype
的通用列表
WITH rtypes as
(select distinct rtype from test_rollup
),
co_names as
(select distinct co_name from test_rollup
)
SELECT
co_name,
rtype,
sum(some_count)
FROM test_rollup
GROUP BY ROLLUP(co_name, rtype)
[...]
最后在两个通用列表的笛卡尔联合中联合,其配对默认为0,减去已经占用的组合:
UNION
SELECT
co_names.co_name,
rtypes.rtype,
0
FROM rtypes, co_names
where not exists
(select 1
from test_rollup
where test_rollup.co_name=co_names.co_name
and rtypes.rtype = test_rollup.rtype)