clickhouse如何实现实现分区排序 类似HIVE的 row_number() over(partition by order by)函数

想必大家对hive实现分区内排名已经掌握的很好了,这篇文章主要就是将的就是用clickhouse如何实现

测试数据

store_codesale_amt
681929
9974111
997460
99742061
43766
867724
867712
348352
34831638
3483108
348324
3483105
348353
34831299
9974120
997427
99743980
99742198
4376288
867715
8677120
867753
867719
34831128
34831653
348348
3483228
348311
348373

hive实现

 -- 建表语句,我是csv导入的 所以用,分割的
 create table store_test (
 store_code string,sale_amt int) 
 row format delimited fields terminated by ",";
 -- 数据导入 看自己的实际情况
 hdfs dfs -put store_code.csv  /user/hive/warehouse/tmp.db/store_test
 --查询语句
select store_code
,sale_amt
,row_number() over(partition by store_code order by sale_amt desc) row_num  
from store_test;

在这里插入图片描述

但是clickhouse 没有 row_number() 函数 该如何实现呢?其实clickhouse是有很多函数的,让我们往下看

clickhouse实现

-- 建表语句
create table tmp.store_test (store_code String, sale_amt Float32 )ENGINE=TinyLog;
--数据导入语
--我直接通过dbever 导入csv文件的
-- 查询sql 
select * from
(
	select store_code,groupArray(sale_amt) as arr_sale_amt , arrayEnumerate(arr_sale_amt) AS row_number
	from ( select *	from tmp.store_test	order by sale_amt desc ) a
	group by store_code
) a ARRAY JOIN row_number , arr_sale_amt
order by store_code ;

在这里插入图片描述
其中我们需要注意的就是一下几个函数了:
先将原始数据排序,因为groupArray不确定顺序


order by sale_amt desc 

创建参数值所有数据的数组。 值可以按任何(不确定)顺序添加到数组中。第二个版本(带有 max_size 参数)将结果数组的大小限制为 max_size 个元素。 例如, groupArray (1) (x) 相当于 [any (x)] 。在某些情况下,您仍然可以依赖执行顺序。这适用于SELECT(查询)来自使用了 ORDER BY 子查询的情况。

groupArray(sale_amt) 

返回数组中的元素下标或者说个数 Array [1, 2, 3, …, length (arr) ],此功能通常与ARRAY JOIN
一起使用。它允许在应用ARRAY JOIN后为每个数组计算一次

arrayEnumerate(arr_sale_amt) 

对于包含数组列的表来说是一种常见的操作,用于生成一个新表,该表具有包含该初始列中的每个单独数组元素的列,而其他列的值将被重复显示。 这是ARRAY JOIN 语句最基本的场景。 类似于 arrayJoin 功能获取每一行并将他们展开到多行(unfold)。而聚合函数则是将多行压缩到一行中(fold或reduce)。其实就是将数组列那行数据打散到多行中。

ARRAY JOIN  

-- 再单独举个官方的列子(clickhouse官网的https://clickhouse.com/docs/en/sql-reference/statements/select/array-join)
CREATE TABLE arrays_test
(
    s String,
    arr Array(UInt8)
) ENGINE = Memory;

INSERT INTO arrays_test
VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []);
┌─s───────────┬─arr─────┐
│ Hello       │ [1,2]   │
│ World       │ [3,4,5] │
│ Goodbye     │ []      │
└─────────────┴─────────┘

SELECT s, arr FROM arrays_test ARRAY JOIN arr;
┌─s─────┬─arr─┐
│ Hello │   1 │
│ Hello │   2 │
│ World │   3 │
│ World │   4 │
│ World │   5 │
└───────┴─────┘
-- 下一个示例使用 LEFT ARRAY JOIN 子句:
SELECT s, arr
FROM arrays_test
LEFT ARRAY JOIN arr;
┌─s───────────┬─arr─┐
│ Hello       │   1 │
│ Hello       │   2 │
│ World       │   3 │
│ World       │   4 │
│ World       │   5 │
│ Goodbye     │   0 │
└─────────────┴─────┘

小伙伴们可能会觉的clickhouse会比较复杂,我们不妨换个角度想,是不是clickhouse很灵活呢?
假如我现在要实现的是要分区范围内topN呢? 就top 1吧,hive是不是还有在外面包一层 where row_num =1;如果是clickhouse的话 就可以直接groupArray(1)(sale_amt) 就行了。是不是觉得很自由 哈哈。当然clickhouse还有其他的实现方式,这里只展示这一种,而且还有特别多的函数等待着大家的挖掘吧,包括我之前有用过的漏斗分析、留存分析等。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值