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

SQL Server 判斷兩日期是否在同一周(以週一為周首):DATEPART 週數與年份雙重校驗

     編輯:程式設計疑難解答

核心邏輯

同一周 ⇔ 同年且同年周號相同。但跨年周(如 12/31 屬於下一年第一周)需特殊處理。

標準判斷函數


-- 參數:@dt1, @dt2 為 date/datetime 類型
-- 返回 1 表示同一周,0 表示不同周
CREATE FUNCTION dbo.IsSameWeek(@dt1 DATE, @dt2 DATE)
RETURNS BIT
AS
BEGIN
    -- 設置週一為周首(SET DATEFIRST 1 對當前會話生效,建議顯式計算避免依賴會話設置)
    -- 方法:以固定基準日期(如 1900-01-01 是週一)計算偏移
    DECLARE @base DATE = '19000101'; -- Monday
    
    -- 計算各自距離基準的周數(整除 7)
    DECLARE @week1 INT = DATEDIFF(DAY, @base, @dt1) / 7;
    DECLARE @week2 INT = DATEDIFF(DAY, @base, @dt2) / 7;
    
    RETURN CASE WHEN @week1 = @week2 THEN 1 ELSE 0 END;
END

DATEPART 版本(依賴 SET DATEFIRST)


-- 需確保會話 DATEFIRST = 1(週一為首)
SET DATEFIRST 1;  -- 僅影響當前連接

SELECT CASE 
    WHEN DATEPART(WEEK, @dt1) = DATEPART(WEEK, @dt2)
     AND DATEPART(YEAR, @dt1) = DATEPART(YEAR, @dt2)
    THEN 1 ELSE 0 END AS IsSameWeek;

跨年周邊界處理(DATEPART 版本補丁)


-- 情況:@dt1=2023-12-31 (週日),@dt2=2024-01-01 (週一) → 實際同一周(ISO 8601 第 1 周)
-- DATEPART(WEEK) 可能判定為不同周,需額外邏輯
SELECT CASE 
    WHEN DATEPART(WEEK, @dt1) = DATEPART(WEEK, @dt2)
     AND DATEPART(YEAR, @dt1) = DATEPART(YEAR, @dt2)
    THEN 1
    -- 跨年周修正:年末最後一天屬於下一年第一周
    WHEN DATEPART(WEEK, @dt1) = DATEPART(WEEK, DATEFROMPARTS(YEAR(@dt1), 12, 31))
     AND DATEPART(WEEKDAY, DATEFROMPARTS(YEAR(@dt1), 12, 31)) <> 1  -- 非週一
     AND YEAR(@dt2) = YEAR(@dt1) + 1
     AND DATEPART(WEEK, @dt2) = 1
    THEN 1
    ELSE 0 END;

推薦做法:ISO 8601 週數計算(不依賴 DATEFIRST)


-- 通用內聯表達式
WITH params AS (
    SELECT @dt1 AS dt1, @dt2 AS dt2
),
weeks AS (
    SELECT 
        dt,
        -- ISO 週數:(日期 - 該年第一個週四) / 7 + 1
        DATEPART(ISO_WEEK, dt) AS iso_week,  -- SQL Server 2008+ 支持 ISO_WEEK
        DATEPART(YEAR, dt) AS yr
    FROM params
    CROSS APPLY (VALUES (dt1), (dt2)) AS t(dt)
)
SELECT CASE WHEN MAX(iso_week) = MIN(iso_week) AND MAX(yr) = MIN(yr) THEN 1 ELSE 0 END
FROM weeks;

關鍵差異表

方法依賴 DATEFIRST跨年周正確性適用版本
DATEDIFF 基準法否正確(固定基準)所有版本
DATEPART(WEEK)是需修正所有版本
DATEPART(ISO_WEEK)否標準正確SQL Server 2008+

「固定基準日 + 整除 7」或「ISO_WEEK」是判斷同一周的工業級寫法,擺脫會話設置依賴,跨年周零 Bug。

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