你好,操作我是条S统计天全yes。 最近在搞新项目,近天一直在迭代,订单这期接到个新需求,操作统计商户近 1天、条S统计天全7天、近天30天、订单全部的操作订单量。 一般而言这种统计类需求都不会直接查库,条S统计天全而是近天交由数仓同学统计,然后回写到业务表或者业务同学直接读数仓表。订单 但是操作由于这是新项目,还没接数仓,免费信息发布网条S统计天全并且量还没起来,近天所以这期就将就着先直接查库实现。 那么问题来了,这 SQL 咋写呢? 直接看简化的表结构: 复制CREATE TABLE order (                        `id` bigint NOT NULL AUTO_INCREMENT,                        `order_no` varchar(32) NOT NULL COMMENT 订单号,                        `user_id` bigint NOT NULL COMMENT 用户id,                        `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间,                        PRIMARY KEY (`id`) USING BTREE,                        KEY `idx_userid_createtime` (`user_id`,`create_time`) USING BTREE                        )1.2.3.4.5.6.7.8.                                                                今天是 2023-09-12 ,如果我们要统计近 1 天的订单量,那么 SQL 很简单: SELECT count(*) FROM order where user_id = xx and time_create >2023-09-12 00:00:00 同理 7天、30天 SELECT count(*) FROM order where user_id = xx and time_create >2023-09-06 00:00:00 SELECT count(*) FROM order where user_id = xx and time_create >2023-08-14 00:00:00 还有全部 SELECT count(*) FROM order where user_id = xx 但是这样一来需要查四次数据库!能不能整个花活,把它压缩成一条 SQL 一次性查询呢? 动脑瓜子刮了刮,还真行!看下面这条 SQL: 复制SELECT statistics, count(*) from (                        SELECT CASE                        WHEN time_create > 2023-09-12 00:00:00 THEN 1                        WHEN time_create > 2023-09-06 00:00:00 THEN 7                        WHEN time_create > 2023-08-14 00:00:00 THEN 30                        ELSE                        all                        END as statistics                        from `order` where user_id = xxx                        ) temp GROUP BY statistics;1.2.3.4.5.6.7.8.9.10.                                                                执行结果如下:  
 思路就是利用 case when 先给对应时间数据打个标记,存放在临时表,然后通过 group by 统计。b2b信息网 我用了一个 4w 多订单数据的用户测试了一下,执行时间是 0.5s ,问题主要出在临时表,一旦数据量起来就不太行,但是暂时没接数仓就先这样顶着了,就前期用用。 突然回想起前公司那时候没招数据同学,让我去整 BI, 那 SQL 写的天花乱坠,感觉把一辈子的 SQL 都写完了,SQL Boy 也不容易啊。  |