2013-08-15 3 views
1

Я использую накопитель для получения некоторых агрегатов и отображения их пользователю в виде таблицы.Обеспечение одинакового количества строк в свертке оракула

Однако я хотел бы убедиться, что в моем свертке количество строк, которые свернуты, является тем же самым, то есть номером самого большого подмножества.

Я думаю, что пример делает то, что я хочу гораздо понятнее, поэтому я настроить простой пример оракула ниже:

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 И 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 

Любые предложения здесь будет очень полезным, так как я хотел бы мое приложение было глупо и просто Tabulate результаты без учета отсутствующих данных. Я бы хотел, чтобы запрос дал мне все, что мне нужно.

Спасибо!

EDIT: Я допинг ... В моем примере выше я хотел сохранить все просто, но сделал ошибку. Вместо RTYPES, являющегося набором {1,2,3} возможных значений, представьте, что это набор {'x', 'y', 'z'} возможных значений ... Я заметил ответ как ответ, потому что он ответил на вопрос, который я задал, и вина на мне :(

+0

Как именно отсутствие B 3 0 строка в накопительном выводе отключает ваше приложение? И почему провайдер данных таблицы «тест» не включает данные В/3 в первую очередь? –

ответ

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 таблица с фактическими данными RTYPES CTE с использованием partition by().

Find out more о разделе присоединение.


Ответ на комментарий:

Если символы, как вы сказали, значение одного символа (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 
+0

Спасибо, это заставило меня на правильном пути, поскольку я упоминал, что rtypes на самом деле не являются целыми целыми числами {1,2,3 ...}, но являются varchars, такими как {x, y, z ...}, но с небольшим массированием Я смог использовать это в свою пользу. – mlnyc

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 's

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)