2017-02-28 31 views
0

我正在處理不在辦公室的報告,正如建議所示,當某人關閉時。我被要求包括返回工作日期。所以我需要編寫一個查詢來檢查這個人關閉的連續日期。我已經設法找到一個接近的查詢,但由於週末而絆倒。 所以默認的數據是:連續幾天不包括週末SQL 2008

StaffCode HolidayDate 
J.Smith  2017-04-03 00:00:00.000 
J.Smith  2017-04-04 00:00:00.000 
J.Smith  2017-04-05 00:00:00.000 
J.Smith  2017-04-06 00:00:00.000 
J.Smith  2017-04-07 00:00:00.000 
J.Smith  2017-04-10 00:00:00.000 
J.Smith  2017-04-11 00:00:00.000 
J.Smith  2017-04-12 00:00:00.000 
J.Smith  2017-04-13 00:00:00.000 
J.Smith  2017-04-18 00:00:00.000 

當我運行該查詢返回

FirstDay   LastDay 
2017-04-03   2017-04-07 
2017-04-10   2017-04-13 
2017-04-18   2017-04-18 

但我要的是

firstDay    lastDay 
2017-04-03    2017-04-13 

這是查詢即時通訊使用,是否有排除週末的方法?

WITH t AS (
    SELECT HolidayDate d,ROW_NUMBER() OVER(ORDER BY HolidayDate) i 
    FROM tblHoliday 
    WHERE StaffCode = 'j.Smith' 
     AND HolidayDate >= '27-Feb-2017' 
    GROUP BY HolidayDate 
) 
SELECT MIN(d),MAX(d) 
FROM t 
GROUP BY DATEDIFF(day,i,d) 
+0

FYI:你會得到更多的答案(更公開程度),如果你需要包含通用標籤(在這種情況下是sql server),然後是 – TheGameiswar

+0

,你的意思是說除了週末以外的連續日期的說明和最大日期。不是嗎?那麼爲什麼2017-04-18是昨天,因爲它不會連續下跌。最後一天應該是2017-04-13 – KumarHarsh

+0

對不起@kumarharsh我使用的例子中有一個銀行假期,所以週一不是工作日。但我可以忽略這些。謝謝。 – GPH

回答

1

這就是Dates表派上用場的地方。有許多博客文章建議將一個Dates表添加到數據庫中,用於需要處理日期的情況。

爲了創建一個Dates表,你可以使用遞歸CTE:

;with dates as (
select cast('19000101' as datetime) [current_date] 
union all 
select dateadd(day, 1, current_date) 
from dates 
where current_date <= cast('20991231' as datetime) 
) 
select 
    [current_date] 
    , NULL [holiday] 
    , case datename(weekday, prev_date) 
     when 'Saturday' 
      then 1 
     when 'Sunday' 
      then 1 
     else 0 
    end  [weekend] 
into Dates 
from dates 
option(maxrecursion 0); 

正如你可以看到我添加的,這可能是在未來有幫助的兩個額外列。如果某個特定的日子是節假日/國家休息日,則可以包含布爾值以指向 - [holiday]列。

如果一天是週末的一天,第三欄還包含布爾值。

因此,使用Dates表,在一個單一的查詢,你可以做這樣的事情(這是不漂亮)

-- I'll also create the sample data and store it into a timeOff table 
create table timeOff (staffCode varchar(25), holidayDate datetime); 

insert [dbo].[timeOff] ([staffCode], [holidayDate]) values (N'J.Smith', CAST(N'2017-04-03T00:00:00.000' AS DateTime)); 
insert [dbo].[timeOff] ([staffCode], [holidayDate]) values (N'J.Smith', CAST(N'2017-04-04T00:00:00.000' AS DateTime)); 
insert [dbo].[timeOff] ([staffCode], [holidayDate]) values (N'J.Smith', CAST(N'2017-04-05T00:00:00.000' AS DateTime)); 
insert [dbo].[timeOff] ([staffCode], [holidayDate]) values (N'J.Smith', CAST(N'2017-04-06T00:00:00.000' AS DateTime)); 
insert [dbo].[timeOff] ([staffCode], [holidayDate]) values (N'J.Smith', CAST(N'2017-04-07T00:00:00.000' AS DateTime)); 
insert [dbo].[timeOff] ([staffCode], [holidayDate]) values (N'J.Smith', CAST(N'2017-04-10T00:00:00.000' AS DateTime)); 
insert [dbo].[timeOff] ([staffCode], [holidayDate]) values (N'J.Smith', CAST(N'2017-04-11T00:00:00.000' AS DateTime)); 
insert [dbo].[timeOff] ([staffCode], [holidayDate]) values (N'J.Smith', CAST(N'2017-04-12T00:00:00.000' AS DateTime)); 
insert [dbo].[timeOff] ([staffCode], [holidayDate]) values (N'J.Smith', CAST(N'2017-04-13T00:00:00.000' AS DateTime)); 
insert [dbo].[timeOff] ([staffCode], [holidayDate]) values (N'J.Smith', CAST(N'2017-04-18T00:00:00.000' AS DateTime)); 

-- And now for the query itself (it's not pretty but I came up with it in a short time) 

select 
    [staffCode] 
    , min([current_date]) [firstDay] 
    , max([current_date]) [lastDay] 
from 
    (select d.[current_date] 
     , t.staffCode 
     , min(case when d.weekend = 0 and t.holidayDate is null then d.[current_date] else null end) over() [last_date] 
    from 
     (select [staffCode] 
      , min(holidayDate) [mindate] 
      , max(holidayDate) [maxdate] 
     from timeOff t 
     where staffcode = 'J.Smith' 
     group by staffCode) r 
    inner join dates d on d.[current_date] between mindate and maxdate 
    left join timeOff t on d.[current_date] = t.holidayDate) r 
where [current_date] < [last_date] 
    and staffCode is not null 
group by staffCode; 
+0

我已經嘗試過實施這個,但是如果在今年晚些時候有另一個請求,它會使用該日期作爲最後一天... – GPH

+0

@GPH對不起,我不明白您的評論。也許你可以在你的問題和預期輸出中添加更多細節? –

+0

好的,如果有2個假期請求。一個在六月一個星期,一個在十二月的一個星期查詢只是看看它可以看到的最後日期。在這種情況下是十二月。因此假期開始日期顯示爲6月1日,結束日期顯示爲12月。 – GPH