首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

MySQL 相同時長歷史區間查詢:將當前時間窗口映射至歷史同長度區間

     編輯:程式設計綜合問答

需求場景

給定開始時間 2014-11-11、結束時間 2014-11-09 (時長 2 天),需查詢歷史同樣長度的區間:2014-11-06 至 2014-11-08。常用於同比分析 (YoY)、環比分析。

核心邏輯

  1. 計算間隔天數:DATEDIFF(end, start) (此例為 2)。
  2. 歷史結束時間 = 當前開始時間 - 1 天 - 間隔天數?實際上:歷史結束 = 當前開始 - INTERVAL 1 DAY,歷史開始 = 歷史結束 - INTERVAL 間隔 DAY。
  3. 通用公式:
    SET @diff = DATEDIFF(@end, @start);
    SET @hist_end = DATE_SUB(@start, INTERVAL 1 DAY);
    SET @hist_start = DATE_SUB(@hist_end, INTERVAL @diff DAY);

SQL 實作 (存儲過程 / 準備語句)

DELIMITER //
CREATE PROCEDURE GetHistoryRange(
    IN p_start DATE, IN p_end DATE,
    OUT p_hist_start DATE, OUT p_hist_end DATE
)
BEGIN
    DECLARE v_diff INT;
    SET v_diff = DATEDIFF(p_end, p_start);
    SET p_hist_end = DATE_SUB(p_start, INTERVAL 1 DAY);
    SET p_hist_start = DATE_SUB(p_hist_end, INTERVAL v_diff DAY);
END //
DELIMITER ;

-- 呼叫
CALL GetHistoryRange('2014-11-11', '2014-11-09', @hs, @he);
SELECT @hs AS hist_start, @he AS hist_end;
-- 結果: 2014-11-06, 2014-11-08

應用層計算更佳 (推薦)

將間隔計算移至應用程式 (Java/Python/Go/C#),優點:

  • SQL 保持簡單、可攜、易緩存計畫。
  • 避免時區、閏年、夏令時等邊界邏輯在 SQL 中處理。
  • 應用層單元測試容易。
// C# 範例
var diff = (end - start).Days;
var histEnd = start.AddDays(-1);
var histStart = histEnd.AddDays(-diff);
string sql = "SELECT * FROM t WHERE dt BETWEEN @hs AND @he";

進階:同比 (YoY) 查詢

若需「去年同期」,直接 DATE_SUB(@start, INTERVAL 1 YEAR)、DATE_SUB(@end, INTERVAL 1 YEAR),但注意閏年 2/29 處理。

總結

「算出間隔,往前推」是核心邏輯。建議在應用層完成日期運算,SQL 僅負責參數化查詢,兼顧效能、可維護與跨資料庫移植。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved