mysql-按年月日統計數據並填充數據

MySQL之按年、月、日統計數據並進行數據填充


一、準備工作:建表

  1. 建表sql:
CREATE TABLE num ( i INT ( 11 ) NULL DEFAULT NULL COMMENT '序號' ) ENGINE = INNODB CHARACTER 
SET = utf8 COLLATE = utf8_general_ci COMMENT = '“存儲數字工具表”' ROW_FORMAT = Dynamic;
  1. 設置數據:
INSERT INTO num (i) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

二、方法闡述

使用mysql進行按日期分組統計數據,並進行填充數據比較簡單,在這裏對該方法進行一個先後順序的講解:

1. 首先,根據笛卡爾乘積(也就是CROSS JOIN),獲取0-99的數據列表。

  • SQL語句:
SELECT
    n1.i + n10.i * 10 AS id 
FROM
    num n1
    CROSS JOIN num AS n10
  • 執行效果:查詢出來的就是0至99的數據,如下圖所示

  • 如果對數據的需求量大,可使用0-999的數據列表,SQL語句爲:SELECT
    n1.i + n10.i * 10 + n100.i * 100 AS id
    FROM
    num n1
    CROSS JOIN num AS n10
    CROSS JOIN num AS n100

2. 獲取時間段(這裏舉例獲取9月份的所有日期)

這裏使用ADDDATE(expr,days)日期函數,其中expr爲指定日期,days爲數字,正數爲增加,負數爲減少。

  • 獲取九月份的所有日期SQL:
SELECT
    adddate( '2018-09-01', numlist.id ) AS 'date' 
FROM
    ( SELECT n1.i + n10.i * 10 AS id FROM num n1 CROSS JOIN num AS n10 ) AS numlist 
WHERE
    adddate( '2018-09-01', numlist.id ) <= date_add( '2018-09-01', INTERVAL 1 MONTH )
  • 執行效果:

  • 注意:因爲sql函數查詢的是從2018年9月1日起,到一個月後的數據,所以會多計算一天,可在代碼中對結果進行處理。

3. 原sql統計結果

  • 我們進行數據統計時,會面臨某一天沒有數據的情況。這裏爲了方便,我們使用 ‘result_jay‘這個單詞作爲原SQL語句的標識
  • 原SQL-‘result_jay’的統計結果,如下圖:

  • 可以觀察到,在我們原來的SQL數據統計結果: 1.統計結果不精確(例子是隻需統計18年9月份數據);2.九月份很多天是沒有數據的

4. 完整SQL

  • 此處爲完整SQL,爲上述步驟結合。先獲取查詢的時間段範圍,然後左關聯我們的統計結果–》大體就是:SELECT [結果列] FROM [時間段範圍] LEFT JOIN [原SQL統計結果] ON [時間段範圍.日期] = [原SQL統計結果.日期] ORDER BY [時間段範圍.日期]
  • SQL語句:
SELECT
    temp.date AS 'name',
    COALESCE ( u.num, 0 ) 'y' 
FROM
    (
    SELECT
        adddate( '2018-09-01', numlist.id ) AS 'date' 
    FROM
        ( SELECT n1.i + n10.i * 10 AS id FROM num n1 CROSS JOIN num AS n10 ) AS numlist 
    WHERE
        adddate( '2018-09-01', numlist.id ) <= date_add( '2018-09-01', INTERVAL 1 MONTH ) 
    ) temp
    LEFT JOIN ( result_jay ) u ON temp.date = u.date 
ORDER BY
    temp.date
  • 執行效果

COALESCE ( u.num, 0 )函數是用來填充結果,若查詢爲null,則賦值0

5. 按年統計(提供三個參數值,如2018年的數據統計,則參數分別爲:2018-01-01,2018-01-01,2018-12-01)

同理,有區分的就是時間段範圍,即完整SQL中from後的主體部分,這裏就不貼完整SQL了。

  • 時間段SQL
SELECT
    adddate( '2018-01-01', INTERVAL numlist.id MONTH ) AS 'date' 
FROM
    (
    SELECT
        * 
    FROM
        ( SELECT n1.i + n10.i * 10 AS id FROM num n1 CROSS JOIN num AS n10 ) a 
    WHERE
        a.id <= 11 
    ) AS numlist 
WHERE
    adddate( '2018-01-01', INTERVAL numlist.id MONTH ) <= '2018-12-01

6. 按周統計

  • 需求爲:選中一個日期,獲取該日期所在周的數據統計。即選擇2018-09-11 星期二,那麼最終的數據統計範圍應爲:2018-09-10 星期一至2018-09-16 星期日七天的數據

  • 時間段SQL:

SELECT
    adddate( ( SELECT subdate( '2018-09-11', date_format( '2018-09-11', '%w' ) - 1 ) ), INTERVAL numlist.id DAY ) AS 'date' 
FROM
    (
    SELECT
        * 
    FROM
        ( SELECT n1.i + n10.i * 10 AS id FROM num n1 CROSS JOIN num AS n10 ) a 
    WHERE
        a.id <= 6 
    ) AS numlist 
WHERE
    adddate( ( SELECT subdate( '2018-09-11', date_format( '2018-09-11', '%w' ) - 1 ) ), INTERVAL numlist.id DAY ) <= ( SELECT subdate( '2018-09-11', date_format( '2018-09-11', '%w' ) - 9 ) )
  • 執行結果:

暫時記錄到這裏,2018年9月10日16:33:42。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章