1

我正在使用汇总来获取一些聚合并以表格形式将它们显示给用户。

但是,我想确保在我的汇总中,汇总的行数相同,即最大子集的数量。

我认为一个例子让我想要的更清楚,所以我在下面的 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'} 可能值......我确实将答案标记为答案,因为它回答了我问的问题,错在我:(

4

2 回答 2

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用于生成RTYPES从 1 到 3(因为它发生 3

rtype在这种情况下的最大数量)。在主查询中,我们右外加入我们的

TEST1带有RTYPESCTE usingpartition by()子句的实际数据的表。

了解有关分区连接的更多信息。


回复评论

如果有字符,如您所说的一个字符值(x,,或y,,它zabc

没关系),在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 
于 2013-08-15T18:32:03.380 回答
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;

用于定义's 和's 的WITH通用列表co_namertype

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)
于 2013-08-15T18:31:39.163 回答