最近在工作中接到了一個需求,要求統計當月以10天為一個周期,每個周期的數據彙總信息。假設有一張表如下: 表table_test中 ID AMOUNT CREATE_DATE 1 50 2017-01-01 2 50 2017-01-09 3 50 2017-01-11 4 50 2017-01-19 ...
最近在工作中接到了一個需求,要求統計當月以10天為一個周期,每個周期的數據彙總信息。假設有一張表如下:
表table_test中
ID AMOUNT CREATE_DATE
1 50 2017-01-01
2 50 2017-01-09
3 50 2017-01-11
4 50 2017-01-19
5 50 2017-01-21
6 50 2017-01-22
7 50 2017-01-24
相當於以CREATE_DATE為組條件,1 - 10,11 -20,21 - 月末,每一個時間段的AMOUNT欄位的和。面對這個需求,首先想到的解決方案為以日期作為參數。使用代碼傳參重覆調用,發現該方法效率極低,後來做出相應優化,使用 UNION ALL 去調用 sql如下
1 SELECT SUM(AMOUT) AS totalAmount FORM TABLE_TEST 2 WHERE CREATE_DATE BETWEEN '2017-01-01' AND '2017-01-10' 3 UNION ALL 4 SELECT SUM(AMOUT) AS totalAmount FORM TABLE_TEST 5 WHERE CREATE_DATE BETWEEN '2017-01-11' AND '2017-01-20' 6 UNION ALL 7 SELECT SUM(AMOUT) AS totalAmount FORM TABLE_TEST 8 WHERE CREATE_DATE BETWEEN '2017-01-21' AND '2017-01-30'
後來數據量大了後發現,效率有些跟不上。就想到了代替的優化SQL如下
1 SELECT 2 sum(amount) totalAmount, 3 floor((day(CREATE_DATE) - day(NOW()))/10) AS TIMESAPN 4 FROM 5 table_test 6 where MONTH(create_date) = MONTH(now()) 7 GROUP BY 8 TIMESAPN --該sql為mysql語句,如果為其他資料庫可替換為其他資料庫函數
關鍵點在於:
floor((day(CREATE_DATE) - day(NOW()))/10) AS TIMESAPN
當 TIMESAPN 為 0 時則在第一個周期,為1則在第二個周期,以此類推,最後在以該欄位為分組條件。完美解決效率問題。可以適當的想一下如果該需求改成按照季度統計。只需要截取日期的月份/4則可以完美解決。也就是說這個sql
基本可以解決按照一段時間去統計的大部分需求。(該sql為博主自己想出來的,適用於本需求。如果有什麼更好的解決方法可以留言。互相學習)