I have some problems with Oracle analytic functions and need help. Here's a generic example:
create table test (item varchar2(10), value varchar2(10));
insert into test values ('item1','value1');
insert into test values ('item1','value1');
insert into test values ('item1','value1');
insert into test values ('item1','value1');
insert into test values ('item1','value1');
insert into test values ('item1','value2');
insert into test values ('item1','value2');
insert into test values ('item3','value2');
insert into test values ('item3','value2');
insert into test values ('item3','value2');
insert into test values ('item5','value1');
insert into test values ('item5','value1');
insert into test values ('item5','value1');
insert into test values ('item5','value1');
insert into test values ('item5','value1');
insert into test values ('item5','value1');
insert into test values ('item5','value1');
insert into test values ('item5','value2');
insert into test values ('item5','value2');
insert into test values ('item5','value2');
select item, value, count(*) c,
sum(count(*)) over () total,
sum(count(*)) over (partition by item) total_by_item,
dense_rank() over (order by count(*) desc) dense_rank
from test
group by item, value
order by 5 desc;
The result of the query is:
ITEM VALUE C TOTAL TOTAL_BY_ITEM DENSE_RANK
---------- ---------- -- ---------- -------------- ----------
item5 value1 7 20 10 1
item5 value2 3 20 10 3
item1 value2 2 20 7 4
item1 value1 5 20 7 2
item3 value2 3 20 3 3
How can I get the items ranked by TOTAL_BY_ITEM? So it would look like this:
ITEM VALUE C TOTAL TOTAL_BY_ITEM WHAT_I_NEED
---------- ---------- -- ---------- -------------- -----------
item5 value1 7 20 10 1
item5 value2 3 20 10 1
item1 value2 2 20 7 2
item1 value1 5 20 7 2
item3 value2 3 20 3 3
Is it possible to achieve this without another join or sub-query? I have a feeling that it is possible. I naturally think that it has to be something like this: dense_rank(count(*)) over (partition by item), like with analytic SUM that I use to get the 5th column, but it doesn't work.
I don't think this is what you are searching for but just for reference without a subquery you can achieve the same result using MODEL clause:
select item, value, c, total, total_by_item, what_i_need
from test
group by item, value
model
dimension by (row_number() over (order by null) d)
measures (
item, value,
count(*) c,
sum(count(*)) over () total,
sum(count(*)) over (partition by item) total_by_item,
1 what_i_need
)
rules (
what_i_need[any] = dense_rank() over (order by total_by_item[cv()] desc)
)
order by 5 desc;
I don't think you can achieve it without subquery otherwise.