rank() 按 count(*) 对一组项目进行排序
Posted
技术标签:
【中文标题】rank() 按 count(*) 对一组项目进行排序【英文标题】:rank() a group of items by count(*) 【发布时间】:2015-12-06 19:08:53 【问题描述】:我在使用 Oracle 分析功能时遇到了一些问题,需要帮助。 这是一个通用示例:
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;
查询的结果是:
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
如何获得按 TOTAL_BY_ITEM 排名的项目?所以它看起来像这样:
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
是否可以在没有另一个连接或子查询的情况下实现这一点?我有一种感觉,这是可能的。我自然认为它必须是这样的:dense_rank(count(*)) over (partition by item),就像我用来获取第 5 列的分析 SUM,但它不起作用。
【问题讨论】:
【参考方案1】:我认为这不是您要搜索的内容,但仅供参考,无需子查询,您可以使用 MODEL 子句获得相同的结果:
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;
我不认为没有子查询你可以实现它。
【讨论】:
您好,谢谢您的回答。这不是我想要的,但非常接近。明天我会在真实数据上试试这个。你真的认为没有子查询就无法实现我所需要的吗?我从未使用过 MODEL 子句。是否有任何关于其性能的细节? MODEL 适用于复杂的转换和报告规则,例如当需要行值之间的依赖关系时。在您的情况下,子查询和两个窗口函数会更简单。由于您没有任何自然的单一维度,因此我需要第三个分析函数来生成替代维度 d。现在我认为最好使用dimension by (item || value d)
而不是使用ROW_NUMBER
。子查询有什么问题?
你知道,现在我开始认为子查询不会有问题。明天我将测试这两种变体的速度。我相信模型和子查询的速度应该很接近吧?无论如何,非常感谢你的想法!
我肯定会选择子查询,它的代码更简洁,而且我认为在这种情况下更快。
我想我会的。这里的问题是我有一个子查询,我在其中读取了同一个表(在我的示例中为测试)两次,并且在某些情况下整体性能很糟糕。现在我不必第二次阅读同一张表,只需阅读结果即可。我不知何故错过了这部分,因此提出了问题。以上是关于rank() 按 count(*) 对一组项目进行排序的主要内容,如果未能解决你的问题,请参考以下文章
[HIVE] rank() dense_rank() row_number()的学习