給定開始時間 2014-11-11、結束時間 2014-11-09 (時長 2 天),需查詢歷史同樣長度的區間:2014-11-06 至 2014-11-08。常用於同比分析 (YoY)、環比分析。
DATEDIFF(end, start) (此例為 2)。歷史結束 = 當前開始 - INTERVAL 1 DAY,歷史開始 = 歷史結束 - INTERVAL 間隔 DAY。SET @diff = DATEDIFF(@end, @start);SET @hist_end = DATE_SUB(@start, INTERVAL 1 DAY);SET @hist_start = DATE_SUB(@hist_end, INTERVAL @diff DAY);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#),優點:
// 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";
若需「去年同期」,直接 DATE_SUB(@start, INTERVAL 1 YEAR)、DATE_SUB(@end, INTERVAL 1 YEAR),但注意閏年 2/29 處理。
「算出間隔,往前推」是核心邏輯。建議在應用層完成日期運算,SQL 僅負責參數化查詢,兼顧效能、可維護與跨資料庫移植。