You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何统计上月周五、周六和周日的天数?

计算上月周五、周六、周日的总天数(SQL Server)

需求说明

需要统计上月内周五、周六、周日这三天的总天数。你已正确定义上月的起止日期:

DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0)  AS start_date,
DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE()) - 1, -1) AS last_date 

但之前尝试的代码仅针对周六周日计算,且逻辑存在偏差,无法满足包含周五的统计需求。


解决方案1:日期差公式计算(无需生成日期序列)

通过计算每个目标星期几在日期范围内的出现次数,再求和。注意SQL Server中DATEPART(dw, ...)的返回值受DATEFIRST设置影响,默认DATEFIRST=7(周日为一周第一天),对应:周日=1、周五=6、周六=7。

DECLARE @start_date DATE = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0);
DECLARE @last_date DATE = DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE()) - 1, -1);

-- 统一设置周日为一周第一天,避免环境差异
SET DATEFIRST 7;

SELECT 
    -- 统计周五数量
    (DATEDIFF(WEEK, @start_date, @last_date) 
     + CASE WHEN DATEPART(dw, @start_date) <= 6 THEN 1 ELSE 0 END 
     - CASE WHEN DATEPART(dw, @last_date) < 6 THEN 1 ELSE 0 END) AS friday_count,
    -- 统计周六数量
    (DATEDIFF(WEEK, @start_date, @last_date) 
     + CASE WHEN DATEPART(dw, @start_date) <= 7 THEN 1 ELSE 0 END 
     - CASE WHEN DATEPART(dw, @last_date) < 7 THEN 1 ELSE 0 END) AS saturday_count,
    -- 统计周日数量
    (DATEDIFF(WEEK, @start_date, @last_date) 
     + CASE WHEN DATEPART(dw, @start_date) <= 1 THEN 1 ELSE 0 END 
     - CASE WHEN DATEPART(dw, @last_date) < 1 THEN 1 ELSE 0 END) AS sunday_count,
    -- 三天总天数
    (
        (DATEDIFF(WEEK, @start_date, @last_date) + CASE WHEN DATEPART(dw, @start_date) <= 6 THEN 1 ELSE 0 END - CASE WHEN DATEPART(dw, @last_date) < 6 THEN 1 ELSE 0 END)
        + (DATEDIFF(WEEK, @start_date, @last_date) + CASE WHEN DATEPART(dw, @start_date) <= 7 THEN 1 ELSE 0 END - CASE WHEN DATEPART(dw, @last_date) < 7 THEN 1 ELSE 0 END)
        + (DATEDIFF(WEEK, @start_date, @last_date) + CASE WHEN DATEPART(dw, @start_date) <= 1 THEN 1 ELSE 0 END - CASE WHEN DATEPART(dw, @last_date) < 1 THEN 1 ELSE 0 END)
    ) AS total_fri_sat_sun;

解决方案2:生成日期序列统计(直观不易错)

生成上月所有日期的序列,再筛选出周五、周六、周日进行计数,逻辑更直观,适合复杂日期筛选场景。

DECLARE @start_date DATE = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0);
DECLARE @last_date DATE = DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE()) - 1, -1);

-- 统一设置周日为一周第一天
SET DATEFIRST 7;

SELECT COUNT(*) AS total_fri_sat_sun
FROM (
    -- 生成上月所有日期
    SELECT DATEADD(DAY, number, @start_date) AS date
    FROM master..spt_values
    WHERE type = 'P' 
        AND DATEADD(DAY, number, @start_date) <= @last_date
) AS all_month_dates
-- 筛选周五(6)、周六(7)、周日(1)
WHERE DATEPART(dw, date) IN (1, 6, 7);

原代码问题说明

你之前的代码仅针对周六、周日计算,且在日期范围的处理上存在错误(比如DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE()) - 3, -1)的偏移逻辑不正确),同时未包含周五的统计,因此无法满足需求。

内容的提问来源于stack exchange,提问作者Frantisek veseli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:12:48