2017-03-01 97 views
2

我正在尝试编写一些将假期分组在一起的代码,并为每个分组创建一个唯一的ID。我遇到的麻烦是创建团体,以知道他们属于一起。如何识别连续工作日期?

默认情况下,如果有人要求一个星期关闭5天将得到一个特定的ID(即223)。因此,会有ID 223的5天假期实例,我可以轻松获得开始和结束日期。但如果有人决定预订星期五休息(ID 224),然后要求星期三和星期四休息(ID 228),然后要求下一个星期一休息(ID 230),那么我有3个独立的实际实际情况一个假期,这里是我需要将它们组合在一起而忽略周末的地方。

我试过DENSE_RANK OVER PARTIONROW_NUMBER OVER ORDER的变体,但是我无法得到它返回我需要的数字。

样本数据和期望的输出

SELECT '01-March-2017' AS HolidayDate, DATEPART(WK,'01-March-2017') AS Dw, 223 AS ID_Field, 1000 AS HolidayID 
UNION ALL 
SELECT '02-March-2017' AS HolidayDate, DATEPART(WK,'02-March-2017') AS Dw, 223, 1000 
UNION ALL 
SELECT '03-March-2017' AS HolidayDate, DATEPART(WK,'03-March-2017') AS Dw, 223, 1000 
UNION ALL 
SELECT '24-March-2017' AS HolidayDate, DATEPART(WK,'24-March-2017') AS Dw, 230 , 1001 
UNION ALL 
SELECT '27-March-2017' AS HolidayDate, DATEPART(WK,'27-March-2017') AS Dw, 235, 1001 
UNION ALL 
SELECT '20-Sep-2017' AS HolidayDate, DATEPART(WK,'20-Sep-2017') AS Dw, 224, 1002 
UNION ALL 
SELECT '27-Sep-2017' AS HolidayDate, DATEPART(WK,'27-Sep-2017') AS Dw, 228, 1003 

所以上面创建一个例子,节假日ID是所需的列输出(随机选择用于样品编号)。 ID字段是假期请求提交时生成的编号。

正如你所看到的223请求进来完成,并具有相同的ID,所以我可以选择MAX(日期),并通过ID_Field得到所需的结果分组。

230和235分别进来但是是同一个假期(作为一个连续的假期),所以我需要将它们用相同的ID进行分组。

最后225和228是完全独立的请求,所以需要唯一的号码。与答案

问题 - enter image description here

+0

请尝试创建http://sqlfiddle.com/案例。 – Anil

+1

3月24日和27日不是连续的日期。请解释你如何知道哪些日子是“相邻的”。你如何考虑假期? –

+0

@GordonLinoff他们是连续工作日 – GPH

回答

2

当LAG时支持LAG不支持

with Holidays 
     as 
     (
      select row_number() over (order by HolidayDate) as n 
        ,HolidayDate 

      from mytable 
     ) 

select h.HolidayDate 

     ,count 
     (
      case 
       when not 
         (
          datediff (day,p.HolidayDate,h.holidayDate) = 1 

         or ( datediff (day,p.HolidayDate,h.HolidayDate) = 3 
          and datename (dw,p.HolidayDate) = 'Friday' 
          ) 
         ) 
       then 1 
      end 
     ) over (order by h.HolidayDate) + 1 as Holiday_id 

from    Holidays as h 
     left join Holidays as p 
     on   p.n = h.n - 1 

order by h.HolidayDate 

select HolidayDate 
     ,count(is_gap) over (order by HolidayDate) + 1 as holiday_id 

from (select HolidayDate 

       ,case 
        when not 
          (
           datediff (day,prev_HolidayDate,HolidayDate) = 1 

          or ( datediff (day,prev_HolidayDate,HolidayDate) = 3 
           and datename (dw,prev_HolidayDate) = 'Friday' 
           ) 
          ) 
        then 1 
       end  as is_gap 

     from (select HolidayDate 
         ,lag(HolidayDate) over (order by HolidayDate) as prev_HolidayDate 

       from mytable 
       ) t 
     ) t 

order by HolidayDate 

+-------------+------------+ 
| HolidayDate | holiday_id | 
+-------------+------------+ 
| 2017-03-01 |   1 | 
| 2017-03-02 |   1 | 
| 2017-03-03 |   1 | 
| 2017-03-24 |   2 | 
| 2017-03-27 |   2 | 
| 2017-09-20 |   3 | 
| 2017-09-27 |   4 | 
+-------------+------------+ 
+0

延迟似乎不支持在SQL 2008中,所以我不能得到这个工作。 – GPH

+0

你有你的解决方案。 –

+0

我真的不打算投弃权票!我很抱歉!试图实现它,但它给了我一个语法错误,我不明白为什么。 - Msg 102,Level 15,State 1,Line 25 “订单”附近的语法不正确。 – GPH