ClickHosue 强大函数 argMin() 和argMax()

    说实话,我喜欢Clickhouse 的函数,简单操作,功能强大。今天需要给大家介绍两个函数,argMin(),argMax()

    argMax():计算 ‘arg’ 最大值 ‘val’ 价值。 如果有几个不同的值 ‘arg’ 对于最大值 ‘val’,遇到的第一个值是输出。argMin() 与argMax() 的功能正好是相反的,如下是Clickhouse官方文档对这个函数的解释,看官应该看知道这个函数是用途了吧。

ClickHosue 强大函数 argMin() 和argMax()_第1张图片

    当然上图是argMin() 函数的简单案例,这里我想到的几个业务场景的使用案例,仅供参考。

drop table if exists salary;
create table salary
(
    `id` Int32,
    `user` String,
    `user_id` Int32,
    `salary` Int32 ,
    `created_at` Datetime ,
    `updated_at` Datetime
) engine = Memory;

insert into salary (id,user,user_id,salary,created_at,updated_at) Values
(1,'Jim',101,10000,'2020-05-01 00:00:00','2020-05-01 00:00:00'),
(2,'Tom',102,15000,'2020-05-01 01:00:00','2020-05-01 00:00:00'),
(3,'Tony',103,20000,'2020-05-01 00:00:00','2020-05-01 00:00:00'),
(4,'Judy',104,25000,'2020-05-01 00:00:00','2020-05-01 00:00:00'),
(5,'Lucy',105,80000,'2020-05-01 00:00:00','2020-05-01 00:00:00');

select * from salary;

 

业务场景一:查看salary 最高和最小的user

// 代码:
select 'Max Salary User' as Type ,argMax(user,salary)  as user from salary
UNION ALL
select 'Min Salary User' as Type, argMin(user,salary)  as user from salary;

//结果:

┌─Type────────────┬─user─┐
│ Max Salary User │ Lucy │
└─────────────────┴──────┘
┌─Type────────────┬─user─┐
│ Min Salary User │ Jim  │
└─────────────────┴──────┘

 

业务场景二:这两个函数可以应用到数据updated 上,非常好用,比如user_id = 101 的salary 数据updated 了,数据产生了一条新的记录;我们可以根据updated_at的时间拿到每个用户一段时间内数据的最新记录或者最早记录;

// 1.插入语句:
insert into salary (id,user,user_id,salary,created_at,updated_at) Values (1,'Jim',101,15000,'2020-05-02 00:00:00','2020-05-02 00:00:00');

// 2.查询:select * from  salary;
┌─id─┬─user─┬─user_id─┬─salary─┬──────────created_at─┬──────────updated_at─┐
│  1 │ Jim  │     101 │  10000 │ 2020-05-01 00:00:00 │ 2020-05-01 00:00:00 │
│  2 │ Tom  │     102 │  15000 │ 2020-05-01 01:00:00 │ 2020-05-01 00:00:00 │
│  3 │ Tony │     103 │  20000 │ 2020-05-01 00:00:00 │ 2020-05-01 00:00:00 │
│  4 │ Judy │     104 │  25000 │ 2020-05-01 00:00:00 │ 2020-05-01 00:00:00 │
│  5 │ Lucy │     105 │  80000 │ 2020-05-01 00:00:00 │ 2020-05-01 00:00:00 │
└────┴──────┴─────────┴────────┴─────────────────────┴─────────────────────┘
┌─id─┬─user─┬─user_id─┬─salary─┬──────────created_at─┬──────────updated_at─┐
│  1 │ Jim  │     101 │  15000 │ 2020-05-02 00:00:00 │ 2020-05-02 00:00:00 │
└────┴──────┴─────────┴────────┴─────────────────────┴─────────────────────┘

// 3.查看每个user的最新工资记录:
select
        id,
        argMax(user,updated_at) as user,
        argMax(user_id,updated_at) as user_id,
        argMax(salary,updated_at) as salary,
        argMax(created_at,updated_at) as created_at
 from salary
 group by id
 order by id asc;

┌─id─┬─user─┬─user_id─┬─salary─┬──────────created_at─┐
│  1 │ Jim  │     101 │  15000 │ 2020-05-02 00:00:00 │
│  2 │ Tom  │     102 │  15000 │ 2020-05-01 01:00:00 │
│  3 │ Tony │     103 │  20000 │ 2020-05-01 00:00:00 │
│  4 │ Judy │     104 │  25000 │ 2020-05-01 00:00:00 │
│  5 │ Lucy │     105 │  80000 │ 2020-05-01 00:00:00 │
└────┴──────┴─────────┴────────┴─────────────────────┘

// 4.argMin()查看最早的数据
select
        id,
        argMin(user,updated_at) as user,
        argMin(user_id,updated_at) as user_id,
        argMin(salary,updated_at) as salary,
        argMin(created_at,updated_at) as created_at
 from salary
 group by id
 order by id asc;

// 5.结果:
┌─id─┬─user─┬─user_id─┬─salary─┬──────────created_at─┐
│  1 │ Jim  │     101 │  10000 │ 2020-05-01 00:00:00 │
│  2 │ Tom  │     102 │  15000 │ 2020-05-01 01:00:00 │
│  3 │ Tony │     103 │  20000 │ 2020-05-01 00:00:00 │
│  4 │ Judy │     104 │  25000 │ 2020-05-01 00:00:00 │
│  5 │ Lucy │     105 │  80000 │ 2020-05-01 00:00:00 │
└────┴──────┴─────────┴────────┴─────────────────────┘

 

业务场景3:想知道公司每个user 的最早期的工资和目前的薪资,以及涨幅和变化情况,根据员工表现合理安排员工的福利:

// 代码:
select user_id,
       argMax(user,updated_at) as user,
        argMin(salary,updated_at) as history_salary,
        argMax(salary,updated_at) as lasted_salary,
        argMax(salary,updated_at) - argMin(salary,updated_at) as difference,
        (argMax(salary,updated_at) - argMin(salary,updated_at)) / argMin(salary,updated_at) as "The percentage of difference"
 from salary
 group by user_id;

// 结果:
┌─user_id─┬─user─┬─history_salary─┬─lasted_salary─┬─difference─┬─The percentage of difference─┐
│     104 │ Judy │          25000 │         25000 │          0 │                            0 │
│     105 │ Lucy │          80000 │         80000 │          0 │                            0 │
│     101 │ Jim  │          10000 │         15000 │       5000 │                          0.5 │
│     103 │ Tony │          20000 │         20000 │          0 │                            0 │
│     102 │ Tom  │          15000 │         15000 │          0 │                            0 │
└─────────┴──────┴────────────────┴───────────────┴────────────┴──────────────────────────────┘

    我们了解了这两个函数,相信还有很多很多的业务场景需要的场景都会用上它们。

    需要注意的是argMax() ,argMin() 函数的时候,如果有 用上where 条件的时候,就要优先去一段时间范围的数据,然后嵌套后再做Where 条件的过滤哦;否则你符合你where过滤的条件的数据,不一定是最新的数据。  

你可能感兴趣的:(ClickHouse)