說實話,我喜歡Clickhouse 的函數,簡單操作,功能強大。今天需要給大家介紹兩個函數,argMin(),argMax()
1.argMax():計算 ‘arg’ 最大值 ‘val’ 價值。 如果有幾個不同的值 ‘arg’ 對於最大值 ‘val’,遇到的第一個值是輸出。argMin() 與argMax() 的功能正好是相反的,👇是Clickhouse官方文檔對這個函數的解釋,看官應該看知道這個函數是用途了吧。
當然上圖是argMin() 函數的簡單案例,這里我想到的幾個業務場景的使用案例,僅供參考。
1 drop table if exists salary; 2 create table salary 3 ( 4 `id` Int32, 5 `user` String, 6 `user_id` Int32, 7 `salary` Int32 , 8 `created_at` Datetime , 9 `updated_at` Datetime 10 ) engine = Memory; 11 12 select * from salary; 13 14 insert into salary (id,user,user_id,salary,created_at,updated_at) Values 15 (1,'Jim',101,10000,'2020-05-01 00:00:00','2020-05-01 00:00:00'), 16 (2,'Tom',102,15000,'2020-05-01 01:00:00','2020-05-01 00:00:00'), 17 (3,'Tony',103,20000,'2020-05-01 00:00:00','2020-05-01 00:00:00'), 18 (4,'Judy',104,25000,'2020-05-01 00:00:00','2020-05-01 00:00:00'), 19 (5,'Lucy',105,80000,'2020-05-01 00:00:00','2020-05-01 00:00:00'), 20 21 select * from salary;
業務場景一:查看salary 最高和最小的user
1 select 'Max Salary User' as Type ,argMax(user,salary) as user from salary 2 UNION ALL 3 select 'Min Salary User' as Type, argMin(user,salary) as user from salary
👇結果:
業務場景二:這兩個函數可以應用到數據updated 上,非常好用,比如user_id = 101 的salary 數據updated 了,數據產生了一條新的記錄;我們可以根據updated_at的時間拿到每個用戶一段時間內數據的最新記錄或者最早記錄;
1 insert into salary (id,user,user_id,salary,created_at,updated_at) Values 2 (1,'Jim',101,15000,'2020-05-02 00:00:00','2020-05-02 00:00:00'); 3 4 select * from salary;
👇結果:
A. 查看每個user的最新工資記錄:
1 select 2 id, 3 argMax(user,updated_at) as user, 4 argMax(user_id,updated_at) as user_id, 5 argMax(salary,updated_at) as salary, 6 argMax(created_at,updated_at) as created_at 7 from salary 8 group by id 9 order by id asc;
最新記錄👇:我們通過結果可以看到user =Jim,是工資有調整了,最開始的時候salary = 10000,目前的salary = 15000,通過argMax() 取到最新的記錄,這個函數間接的實現了數據的updated 的功能,clickhouse 既可以查看歷史的所有數據,又可以很好的查看最新的數據。
argMin()查看最早的數據:
1 select 2 id, 3 argMin(user,updated_at) as user, 4 argMin(user_id,updated_at) as user_id, 5 argMin(salary,updated_at) as salary, 6 argMin(created_at,updated_at) as created_at 7 from salary 8 group by id 9 order by id asc;
結果👇:
業務場景想象:想知道公司每個user 的最早期的工資和目前的薪資,以及漲幅和變化情況,根據員工表現合理安排員工的福利:
1 select user_id, 2 argMax(user,updated_at) as user, 3 argMin(salary,updated_at) as history_salary, 4 argMax(salary,updated_at) as lasted_salary, 5 argMax(salary,updated_at) - argMin(salary,updated_at) as difference, 6 (argMax(salary,updated_at) - argMin(salary,updated_at)) / argMin(salary,updated_at) as "The percentage of difference" 7 from salary 8 group by user_id;
結果👇:
我們了解了這兩個函數,相信還有很多很多的業務場景需要的場景都會用上它們。
Please Note:
需要注意的是argMax() ,argMin() 函數的時候,如果有 用上where 條件的時候,就要優先去一段時間范圍的數據,然后嵌套后再做Where 條件的過濾哦;否則你符合你where過濾的條件的數據,不一定是最新的數據。🤔