在SQL中计算营业时间

时间:2012-03-15 10:25:56

标签: sql sql-server-2005

我需要计算日期之间的营业时间。

我需要在那几个小时后排除。

  1. 工作时间(下午6点至早上9点)
  2. 周末
  3. 假日
  4. 对于假期我有一个表HOLIDAYS

    DATE        NAME
    ----------------------------------
    2012-01-02  New Year's Day
    2012-04-06  Good Friday
    2012-04-09  Easter Monday
    
    

    注意:
    1.我有几个小时的开始和结束日期('2012/03/15 14:00'到'2012/03/22 17:30')。
    2.我正在使用Sql Server 2005,因此我没有日期类型DATE或TIME。

1 个答案:

答案 0 :(得分:3)

试试这个。

DECLARE @start_date DATETIME 
DECLARE @stop_date DATETIME 
DECLARE @days INT

SELECT @start_date = '2012/03/15 14:00', @stop_date = '2012/03/22 17:30'

SELECT @days = DATEDIFF(DAY, CAST(FLOOR(CAST(@start_date AS FLOAT)) AS DATETIME), CAST(FLOOR(CAST(@stop_date AS FLOAT)) AS DATETIME)) + 1

;WITH CTE_ALL_DAYS AS (
    SELECT TOP (@days) 
        DATEADD(DAY, rn, CAST(FLOOR(CAST(@start_date AS FLOAT)) AS DATETIME)) AS dt
    FROM (
        SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) - 1 AS rn
        FROM master.sys.all_columns AS a
        CROSS JOIN master.sys.all_columns AS b
        ) AS tally
)
SELECT SUM(
        CASE
            WHEN dt = CAST(FLOOR(CAST(@start_date AS FLOAT)) AS DATETIME) THEN 
                CASE 
                    WHEN DATEDIFF(HOUR, @start_date, DATEADD(HOUR, 18, CAST(FLOOR(CAST(@start_date AS FLOAT)) AS DATETIME))) > 9 THEN 9
                    WHEN DATEDIFF(HOUR, @start_date, DATEADD(HOUR, 18, CAST(FLOOR(CAST(@start_date AS FLOAT)) AS DATETIME))) > 0 THEN DATEDIFF(HOUR, @start_date, DATEADD(HOUR, 18, CAST(FLOOR(CAST(@start_date AS FLOAT)) AS DATETIME))) 
                    ELSE 0 
                END
            WHEN dt = CAST(FLOOR(CAST(@stop_date AS FLOAT)) AS DATETIME) THEN 
                CASE 
                    WHEN DATEDIFF(HOUR, DATEADD(HOUR, 9, CAST(FLOOR(CAST(@stop_date AS FLOAT)) AS DATETIME)), @stop_date) > 9 THEN 9
                    WHEN DATEDIFF(HOUR, DATEADD(HOUR, 9, CAST(FLOOR(CAST(@stop_date AS FLOAT)) AS DATETIME)), @stop_date) > 0 THEN DATEDIFF(HOUR, DATEADD(HOUR, 9, CAST(FLOOR(CAST(@stop_date AS FLOAT)) AS DATETIME)), @stop_date) 
                    ELSE 0 
                END 
            ELSE 9      
        END
    )
FROM CTE_ALL_DAYS   
WHERE 
    NOT DATEPART(weekday, dt) IN (1, 7)
    AND NOT dt IN (SELECT [DATE] FROM HOLIDAYS)
相关问题