一、创建测试数据
测试数据场景为各用户ID拥有手机号信息及变更记录。我们需要根据更新时间取各用户ID最新的手机号信息。
CREATE TABLE default.row_number
(
`user_id` String,
`user_phone` String,
`create_time` DateTime,
`update_time` DateTime
)
ENGINE = MergeTree
ORDER BY user_id
SETTINGS index_granularity = 8192;
insert into default.row_number values
('1','13234567891','2021-07-14 11:54:19','2021-07-14 11:54:19'),
('1','13234567890','2021-07-14 11:40:09','2021-07-14 11:40:09'),
('1','13234567892','2021-07-14 11:54:37','2021-07-14 11:54:37'),
('2','13234567894','2021-07-14 11:57:22','2021-07-14 11:57:22'),
('2','13234567893','2021-07-14 11:55:05','2021-07-14 11:55:05'),
('3','13234567896','2021-07-14 11:57:45','2021-07-14 11:57:45'),
('3','13234567895','2021-07-14 11:57:30','2021-07-14 11:57:30');
二、groupArray
groupArray可以将字段放在一个数组里。groupArray(num)(x)中,num参数限制生成的数组含有的元素的个数。
select user_id,
groupArray(1)(user_phone) AS user_phone,
groupArray(1)(create_time) AS create_time,
groupArray(1)(update_time) AS update_time
from (select user_id,
user_phone,
create_time,
update_time
from default.row_number
ORDER BY update_time desc
) a
group by user_id
order by user_id;
注:这种方法存在弊端,数据量小时不影响结果输出准确性,但当数据量较大时可能出现异常情况,子查询未形成缓存表就执行了聚合函数。并且这种方法SQL逻辑较复杂,性能较差,耗内存。
三、argMax
argMax(arg,val):计算 ‘arg’ 最大值 ‘val’ 价值,argMin() 与argMax() 的功能正好是相反的,以下为官方示例:
上图是argMin() 函数的简单案例,我们可以应用argMax函数对测试数据实现同样的效果。这种方法SQL逻辑更简单,性能更好。
select user_id,
argMax(user_phone,update_time) as phone,
argMax(create_time,update_time) as time
from row_number
group by user_id
order by user_id;