2014-05-23 33 views
0

我希望有人能幫助我。我將下面的簡單示例: 爲了計費目的,我需要跳過假期和週末來設置開票日期的正確截止日期。 我有一張假期表,裏面包含了公司所有的假期(可能包含一些週末這樣的週六 - 現在不太確定像銀行這樣的公司,現在我們不能考慮特殊情況)。在表中計算連續假期/週末

我需要找出連續的假期在數據庫連續的週末。

對於數據庫中,例如假日數據:

EXCP_DATE ID 
----------- ---------- -------------------- ---------- 
3/29/2013 1 
4/1/2013 1 
12/9/2013 1 
12/10/2013 1 
12/25/2013 1 
12/26/2013 1 
12/27/2013 1 
12/28/2013 1 

我需要假期和週末的下「出現次數」列中的數字。連續假期/週末 我CONSECUTIVE_DAY:1表示的日期已連續假期/週末

ID EXCP_DATE WeekDay CONSECUTIVE_DAY OCCURENCES 
1 3/29/2013 FRIDAY 1 3 
2 4/1/2013 MONDAY 0 1 
3 12/9/2013 MONDAY 1 2 
4 12/10/2013 TUESDAY 0 1 
5 12/25/2013 WEDNESDAY 1 5 
6 12/26/2013 THURSDAY 1 4 
7 12/27/2013 FRIDAY 1 3 
8 12/28/2013 SATURDAY 1 2 

下面是一個適用於大多數情況下查詢。它只有在連續兩個假期以上纔會失敗,因爲它只會引導一步。

SELECT A.* 
    ,CASE 
     WHEN CONSECUTIVE_DAY = 1 
      THEN CASE 
        WHEN upper(datename(weekday, EXCP_DATE)) = 'FRIDAY' 
         AND LEAD(EXCP_DATE) OVER (
          ORDER BY EXCP_DATE 
          ) = (EXCP_DATE + 3) 
         THEN DATEdiff(dd, EXCP_DATE, LEAD(EXCP_DATE) OVER (
            ORDER BY EXCP_DATE 
            )) + 1 
        WHEN upper(datename(weekday, EXCP_DATE)) = 'FRIDAY' 
         AND LEAD(EXCP_DATE) OVER (
          ORDER BY EXCP_DATE 
          ) <> (EXCP_DATE + 3) 
         THEN 3 
        ELSE DATEdiff(dd, EXCP_DATE, LEAD(EXCP_DATE) OVER (
           ORDER BY EXCP_DATE 
           )) + 1 
        END 
     ELSE CONSECUTIVE_DAY 
     END OCCURENCES 
FROM (
    SELECT T.* 
     ,upper(datename(weekday, EXCP_DATE)) WeekDay 
     ,Lead(EXCP_DATE, 1, EXCP_DATE) OVER (
      ORDER BY EXCP_DATE 
      ) Lead 
     ,EXCP_DATE + 1 [EXCP_DATE + 1] 
     ,EXCP_DATE + 3 [EXCP_DATE +3] 
     ,datename(weekday, EXCP_DATE + 3) [DateName_EXCP_DATE +3] 
     , 
     --------------------------- 
     CASE 
      WHEN Lead(EXCP_DATE, 1, EXCP_DATE) OVER (
        ORDER BY EXCP_DATE 
        ) = EXCP_DATE + 1 
       THEN 1 
      WHEN upper(datename(weekday, EXCP_DATE)) = 'FRIDAY' 
       AND LEAD(EXCP_DATE) OVER (
        ORDER BY EXCP_DATE 
        ) = EXCP_DATE + 3 
       THEN 1 
      WHEN upper(datename(weekday, EXCP_DATE)) = 'SATURDAY' 
       AND LEAD(EXCP_DATE) OVER (
        ORDER BY EXCP_DATE 
        ) = EXCP_DATE + 2 
       THEN 1 
      ELSE 0 
      END CONSECUTIVE_DAY 
    FROM TEST1 T 
    ) A 

----------------------------------- Number 5 and 6 are not correct 。我如何對Lead進行遞歸?

結果:

ID EXCP_DATE WeekDay Lead EXCP_DATE + 1 EXCP_DATE +3 DateName_EXCP_DATE +3 CONSECUTIVE_DAY OCCURENCES 
1 3/29/2013 FRIDAY 4/1/2013 3/30/2013 4/1/2013 Monday 1 4 
2 4/1/2013 MONDAY 12/9/2013 4/2/2013 4/4/2013 Thursday 0 0 
3 12/9/2013 MONDAY 12/10/2013 12/10/2013 12/12/2013 Thursday 1 2 
4 12/10/2013 TUESDAY 12/25/2013 12/11/2013 12/13/2013 Friday 0 0 
5 12/25/2013 WEDNESDAY 12/26/2013 12/26/2013 12/28/2013 Saturday 1 2 
6 12/26/2013 THURSDAY 12/27/2013 12/27/2013 12/29/2013 Sunday 1 2 
8 12/27/2013 FRIDAY 12/28/2013 12/28/2013 12/30/2013 Monday 1 3 
7 12/28/2013 SATURDAY 12/28/2013 12/29/2013 12/31/2013 Tuesday 0 0 

感謝您的幫助。

+1

您如何期待任何人閱讀和理解?請適當格式化該帖子。 – EkoostikMartin

+1

我添加了sql-server標籤,因爲代碼看起來像SQL Server(和版本2012+)。 –

回答

0

我會用不同的方法。創建一個函數,在提供開始日期時返回下一個有效的商業日期。

例如,假設某人的截止日期是2014年5月24日(這是一個星期六)。您可以將該值傳遞給函數以返回下一個有效的業務日期。這是我寫的一個快速功能。

此函數假定您有一張名爲[Holidays]的表格,其中包含您公司的假日日期。

CREATE FUNCTION [dbo].[NextBusinessDay] 
(
    @BusinessDay DATE 
) 
RETURNS DATE AS 
BEGIN 
    DECLARE @GoodDay DATE; 
    WITH cte AS (
     SELECT @BusinessDay AS good_date 
     UNION ALL 
     SELECT DateAdd(d,1,good_date) 
     FROM CTE 
     WHERE good_date < DateAdd(d,7,@BusinessDay) 
    ) 
    SELECT @GoodDay = min(good_date) FROM cte 
    WHERE Upper(DateName(WEEKDAY, good_date)) NOT IN ('SATURDAY','SUNDAY') 
    AND NOT EXISTS (SELECT [Holiday] FROM [Holidays] WHERE [Holiday] = good_date); 
    RETURN @GoodDay; 
END; 

然後,您只需通過日期。

​​

在上面的例子中,這將返回2014年5月27日,自2014年5月24日和2014年5月25日是週末,和2014年5月26日是一個假期(如果你有紀念在你的假期表中的一天)。

相關問題