ClickHouse的case when用法,及利用它实现按条件统计数量

文章目录

    • ClickHouse介绍
    • case when介绍
    • case when结合sum函数统计数量
    • 生产场景使用

ClickHouse介绍

  • ClickHouse是由俄罗斯的Yandex公司开发的一款快速、可扩展的列式数据库管理系统。它专门针对OLAP场景设计,在海量数据分析和查询方面具有出色的性能表现,同时还能支持实时数据插入和更新。
  • ClickHouse采用了面向列的存储方式,具有较高的压缩比和查询速度。它支持SQL语言,并提供了一系列丰富的函数库,可满足各种复杂的数据分析需求。同时,ClickHouse还支持数据分区和分片,可实现横向扩展
  • ClickHouse使用C++编写,可在LinuxWindows等操作系统上运行。它还支持RESTful APIJDBC等多种接口,方便与其他系统进行集成。由于其出色的性能和可扩展性,ClickHouse被许多企业用于大规模数据处理和分析,如YandexCloudFlareKenshoo
  • 在国内,ClickHouse也被各大厂青睐和使用,例如京东、腾讯、哔哩哔哩、字节跳动等
  • 从我个人两年多的使用经验来说,它对于中小型公司,只有部分业务涉及大数据处理的场景,也很适用,我们可以使用单体ClickHouse作为大数据存储和分析组件,后续可以根据业务增长自由扩展
  • 在使用ClickHouse时,我们可以尽情的存储我们的海量数据,也可以毫不忌讳的直接把海量数据使用SQL进行计算和统计
  • 下面就介绍下我用到的CASE WHEN语句的用法

case when介绍

  • 先说下我的需求,我需要根据不同的值进行数量统计
  • ClickHouse中的CASE WHEN用法与SQL标准中的用法基本相同,用于实现条件分支逻辑
  • CASE WHEN的基本语法如下:
CASE [expression]
    WHEN condition_1 THEN result_1
    WHEN condition_2 THEN result_2
    ...
    WHEN condition_n THEN result_n
    [ELSE else_result]
END
  • 其中,[expression]为可选项,若提供,则在进行条件判断之前对其进行计算。
  • condition是一个可以返回真或假的表达式,如果返回真,则返回相应的result,否则会继续判断下一个条件
  • 如果没有匹配的条件,则返回ELSE子句中的else_result,如果没有提供ELSE子句,则返回NULL
  • 下面是一个简单的示例,将分数数值转换为等级(A/B/C/D):
SELECT *,
    CASE
        WHEN grade >= 90 THEN 'A'
        WHEN grade >= 80 THEN 'B'
        WHEN grade >= 70 THEN 'C'
        ELSE 'D'
    END AS grade_level
FROM student_scores
  • 在上述代码中,我们使用了一个不带参数的CASE WHEN语句来根据成绩返回对应的等级。
  • ClickHouse中,CASE WHEN语句也可以嵌套使用,可以根据实际需求编写更为复杂的条件分支逻辑。

case when结合sum函数统计数量

  • 上面的示例是一种简单的值转换,由数值转换为字母等级,下面我的需求是需要统计不同等级的数量
  • 统计数量,就需要case when结合sum函数来实现
  • clickhouse中使用case when语句统计数量需要使用以下语法:
SELECT
  COUNT(*) AS count,
  SUM(CASE 
        WHEN column_name = 'value_1' THEN 1
        WHEN column_name = 'value_2' THEN 1
        ELSE 0
      END) AS count_1_and_2,
  SUM(CASE 
        WHEN column_name IN ('value_3', 'value_4') THEN 1
        ELSE 0
      END) AS count_3_and_4
FROM table_name
  • 其中,count_1_and_2将统计column_namevalue_1value_2的行数,count_3_and_4将统计column_namevalue_3value_4的行数
  • sum结合 case when,可以统计对应条件的数量,算是一种比较常用的按类型统计
  • 除了sum,其他数学函数也可以使用,根据需要都可以使用

生产场景使用

  • 我有一张交通事件表,记录路口实时发生的交通事件,如拥堵、逆行、闯红灯、行人滞留斑马线等
  • 建表SQL语句(部分)如下:
DROP table if exists radar.traffic_event;
CREATE TABLE radar.traffic_event
(
    `time_stamp` DateTime COMMENT '雷达上报时间',
    `intersection_number` Int32 COMMENT '路口编号'
    `event_status` String COMMENT '事件状态(1-交通事件,2-事件恢复)',
    `event_code` String COMMENT '事件码 1-拥堵(或拥堵恢复)、 2-逆行、 3-溢出(溢出恢复)'
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(time_stamp)
PRIMARY KEY time_stamp
ORDER BY time_stamp
TTL time_stamp + toIntervalYear(5)
SETTINGS index_granularity = 8192, old_parts_lifetime = 300, max_suspicious_broken_parts = 1000
  • 我现在有个展示需求,需要按照一定时间粒度统计各个交通事件发生的频次,列表展示
  • 我现在需要一次性查出来,各个类型的数量,按照小时聚合统计,使用sum(case when)刚好满足需求
  • 查询SQL如下:
SELECT
	toStartOfInterval(time_stamp , INTERVAL 1 HOUR) as time_stamp2 ,
	sum(case when event_code in ('CONGESTION','SEVERE_CONGESTION','MILD_CONGESTION') then 1 end) as congestionCount,
	sum(case when event_code = 'REVERSE_DRIVE' then 1 end) as reverseDriveCount,
	sum(case when event_code = 'PEDESTRIAN_DETENTION' then 1 end) as detainCount
from
	traffic_event 
WHERE
	event_status = 'EVENT_DETECTED'
	and time_stamp > '2023-05-09 14:05:52'
GROUP BY time_stamp2
order by time_stamp2 
  • 有需要的,可以自己建表,插入些数据试下,可以直接使用这些SQL

你可能感兴趣的:(ClickHouse,数据库及存储技术,clickhouse,数据库,sql,case,when,条件聚合统计)