SQL騷操作,一條SQL 統(tǒng)計近 7天、30天、全部的訂單量
你好,我是yes。
最近在搞新項目,一直在迭代,這期接到個新需求,統(tǒng)計商戶近 1天、7天、30天、全部的訂單量。
一般而言這種統(tǒng)計類需求都不會直接查庫,而是交由數(shù)倉同學(xué)統(tǒng)計,然后回寫到業(yè)務(wù)表或者業(yè)務(wù)同學(xué)直接讀數(shù)倉表。
但是由于這是新項目,還沒接數(shù)倉,并且量還沒起來,所以這期就將就著先直接查庫實現(xiàn)。
那么問題來了,這 SQL 咋寫呢?
直接看簡化的表結(jié)構(gòu):
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 '創(chuàng)建時間',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_userid_createtime` (`user_id`,`create_time`) USING BTREE
)
今天是 2023-09-12 ,如果我們要統(tǒng)計近 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'
但是這樣一來需要查四次數(shù)據(jù)庫!能不能整個花活,把它壓縮成一條 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;
執(zhí)行結(jié)果如下:
思路就是利用 case when 先給對應(yīng)時間數(shù)據(jù)打個標(biāo)記,存放在臨時表,然后通過 group by 統(tǒng)計。
我用了一個 4w 多訂單數(shù)據(jù)的用戶測試了一下,執(zhí)行時間是 0.5s ,問題主要出在臨時表,一旦數(shù)據(jù)量起來就不太行,但是暫時沒接數(shù)倉就先這樣頂著了,就前期用用。
突然回想起前公司那時候沒招數(shù)據(jù)同學(xué),讓我去整 BI, 那 SQL 寫的天花亂墜,感覺把一輩子的 SQL 都寫完了,SQL Boy 也不容易啊。