SQL排除假期,周末和未来几天

时间:2012-12-21 06:06:17

标签: sql sql-server

我创建了一个存储过程,如下所示:

ALTER PROCEDURE reminders
AS

BEGIN
SET NOCOUNT ON;

DECLARE @MyDate    DATE, 
@FirstDate DATE, 
@LastDate  DATE 

SELECT @MyDate = Getdate()


 SELECT @FirstDate = CONVERT(VARCHAR(25), Dateadd(dd, -( Day(@mydate) - 1 ), @mydate), 100),  @LastDate = CONVERT(VARCHAR(25), Dateadd(dd, -( Day( Dateadd(mm, 1, @mydate)) ), 
 Dateadd(mm, 1, @mydate)), 100) 


DECLARE @AllDates TABLE 
( 
datevalue DATE
) 
DECLARE @Lastday INT 

SET @Lastday = Datepart(d, @LastDate) 

DECLARE @Days INT 

SET @Days = 1 


WHILE @Days <= @Lastday 
BEGIN 
INSERT INTO @AllDates 
SELECT @FirstDate 

SET @FirstDate = Dateadd(d, 1, @FirstDate) 
SET @Days = @Days + 1 
END 


SELECT AD.datevalue 
FROM   @AllDates AD 
LEFT OUTER JOIN EmpLog EL 
ON AD.datevalue = EL.Date
LEFT OUTER JOIN holiday H 
ON AD.datevalue = H.Date

WHERE  EL.Date IS NULL 
AND H.Date IS NULL  
AND DATENAME(dw,AD.DateValue) NOT IN ('Saturday','Sunday')

END

我需要的是输出不应包括未来的日子。 今天的Ex Date是12-21-2012,该代码的输出包括12-22-2012到12-31-2012, 而且,我希望代码仅在当前日期之前输出16天。 防爆。今天的日期是12-21-2012,因此该代码的输出将在11月30日至12月21日排除假期和周末。

谢谢

2 个答案:

答案 0 :(得分:0)

Justine - 使用此程序。它接受开始日期和结束日期作为输入参数。它将在这两个日期之间为您提供所需的结果。

ALTER PROCEDURE reminders

@FirstDate DATE, 
@LastDate  DATE 

AS
BEGIN
SET NOCOUNT ON;

DECLARE @AllDates TABLE 
( 
datevalue DATE
) 

WHILE @FirstDate <= @Lastdate 
BEGIN 
INSERT INTO @AllDates 
SELECT @FirstDate 
SET @FirstDate = Dateadd(d, 1, @FirstDate) 
END 


SELECT AD.datevalue 
FROM   @AllDates AD 
LEFT OUTER JOIN EmpLog EL 
ON AD.datevalue = EL.Date
LEFT OUTER JOIN holiday H 
ON AD.datevalue = H.Date

WHERE  EL.Date IS NULL 
AND H.Date IS NULL  
AND DATENAME(dw,AD.DateValue) NOT IN ('Saturday','Sunday')

END

拉​​吉

答案 1 :(得分:0)

在SQLServer2005 +中使用递归CTE

ALTER PROCEDURE reminders
AS
BEGIN
  SET NOCOUNT ON;
  DECLARE @MyDate date = GETDATE()
  ;WITH cte AS
   (
    SELECT @MyDate AS datevalue,
           1 AS [count_all_days],
           CASE WHEN DATENAME(dw, DATEADD(dd, - 1, @MyDate)) IN ('Saturday', 'Sunday') THEN 1 ELSE 0 END AS [count_week_days]
    UNION ALL
    SELECT DATEADD(dd, - [count_all_days], @MyDate), 
           [count_all_days] + 1,
           CASE WHEN DATENAME(dw, DATEADD(dd, - [count_all_days], @MyDate)) IN ('Saturday', 'Sunday') THEN [count_week_days] + 1 ELSE [count_week_days] END
    FROM cte
    WHERE [count_all_days] - [count_week_days] < 16
    )
    SELECT AD.datevalue
    FROM cte AD LEFT JOIN EmpLog EL ON AD.datevalue = EL.Date
                LEFT JOIN holiday H ON AD.datevalue = H.Date
    WHERE EL.Date IS NULL AND H.Date IS NULL  AND DATENAME(dw, AD.DateValue) NOT IN ('Saturday', 'Sunday')
END