ClickHouse应用随笔1——按两个非数值型字段分别去重查询

前言

平时 SQL 用得少,最近刚好需要在 Metabase 上用与 SQL 差不多的 ClickHouse 语句搭数据仪表盘,于是遇到了以下问题,在查询时,需要按两个字段分别去重的查询,而非单纯的做联合去重,如先按字段 A 去重后,再查看 B 字段的非重复项数量(A 和 B 都是非数值型的)。

如果是 SQL 语句,我们很容易能想到利用 ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN) 这个语法来实现,原理为:根据某一字段分组,在分组内根据另字段排序,然后新增一列给每一行数据标记一个行号,最后通过 row_number = 1 即可获得分组内的第一行数据了。

然鹅在 ClickHouse 语句中并不支持该语法,只能另寻它法。

表结构及查询需求

表结构

time user_id ip
January 1, 2021, 08:33 AM 112233abc 1.1.2.3
January 1, 2021, 09:00 AM 221133bac 1.1.2.3
January 1, 2021, 09:20 AM 113322acb 1.1.3.2
January 1, 2021, 10:12 AM 113322acb 1.1.3.4
January 1, 2021, 11:01 AM 221133bac 1.2.1.3
January 1, 2021, 11:45 AM 112233abc 1.2.1.3
…… …… ……

查询需求:在表 User_login 中,查看每日按 user_id 去重后的非重复 ip 数。

ClickHouse中的方法

select
    day,
    count(distinct(uid)) DAU
from
    (select
        date(time) day,
        ip,
        max(user_id) uid
    from
        User_login
    group by
        day,
        ip)
group by
    day

这里其实只是简单的用了个 max() 函数将 user_id 取了依照ASCII字符顺序排序的最大值。

起初在写查询时,由于 user_id 是字符型而非数值,完全忽略了max() 这个函数的存在,查询语句写得一度让我怀疑人生(手动捂脸),代码一长串一长串的改…到头来脑一抽,那就试试 max() 吧……emmm,成了!

这也是目前能想到的比较简单粗暴的方法了,如果大佬们有其他方法欢迎在评论区交流交流w(゚Д゚)w…

你可能感兴趣的:(ClickHouse应用随笔1——按两个非数值型字段分别去重查询)