SQL實現日期自動填充


SQL實現日期自動填充

在使用SQL進行數據處理時,經常會遇到需要補齊日期的需求,今天聊一聊幾個主流數據庫的實現方式。

下面以生成2021-09-01到2021-09-30之間所有日期為例進行說明

Oracle

connect by的遞歸查詢還是比較強大的,實現起來也比較簡單

SELECT TO_DATE('2021-08-31', 'yyyy-mm-dd') + ROWNUM as date_list
FROM DUAL
CONNECT BY ROWNUM <= 30;

MySQL

  • 在MySQL8之前的版本,通過先生成序號列表,再使用起始日期增加相應天數來實現
SELECT date_add('2021-09-01', INTERVAL d_num DAY) date_list
FROM (
-- 使用@變量的形式,得到序號列表
SELECT @num := @num + 1 as d_num
from
-- 通過兩個臨時表做笛卡爾積,得到一個記錄數為兩個表乘積的數據
-- 此處為5*6=30天
(SELECT 1 UNION SELECT 2 UNION 
 SELECT 3 UNION SELECT 4 UNION SELECT 5) t1,
    
(SELECT 1 UNION SELECT 2 UNION SELECT 3
 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) t2,
-- 聲明從-1開始
(SELECT @num := -1) a
) a
  • 在MySQL8以后,可以通過遞歸語法實現
WITH RECURSIVE cte (d) AS
(SELECT '2021-09-01'
 UNION ALL
 SELECT d + INTERVAL 1 DAY
 FROM cte
 WHERE d + INTERVAL 1 DAY <= '2021-09-30')
SELECT *
FROM cte
ORDER BY cte.d;

PostgreSQL

實現起來比較簡單粗暴,直接使用generate_series函數生成

select generate_series(
    '2021-09-01'::date,
    '2021-09-30',
    '1 day') date_list;

Hive 函數

在Hive上面的實現相對復雜一些,實現思路是構建出起始日期需要增加天數,然后使用起始日期增加相應的天數實現日期補齊

  1. 使用datediff計算起始日期與結束日期的日期差的天數n

  2. 使用repeat生成一個字符串s,字符串內容為重復某字符n遍

  3. 使用split將字符串s拆分成數組a

  4. 使用posexplode將數組a轉為n行帶序號的數據

    posexplode說明:behaves like explode for arrays, but includes the position of items in the original array

  5. 通過date_add函數,從起始日期加上序號達到日期補齊

注:本SQL是在Hive3.1.2中執行

select date_add('2021-09-01', a.pos) as d
from (select posexplode(
    split(
        repeat('m', 29)
      , 'm')
)) a

歡迎關注微信公眾號:數據研發技術,干貨滿滿


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM