2017-02-28 51 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

相关问题