为工作日俱乐部排行

时间:2023-03-11
本文介绍了为工作日俱乐部排行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有如下数据:

StartDate     EndDate    Duration 
----------
41890         41892       3
41898         41900       3
41906         41907       2
41910         41910       1

StartDate 和 EndDate 是日历中任何日期的各自 ID 值.我想计算连续几天的持续时间总和.在这里,我想包括周末的日子.例如.在上面的数据中,假设 41908 和 41909 是周末,那么我需要的结果集应该如下所示.

StartDate and EndDate are respective ID values for any dates from calendar. I want to calculate the sum of duration for consecutive days. Here I want to include the days which are weekends. E.g. in the above data, let's say 41908 and 41909 are weekends, then my required result set should look like below.

我已经有另一个 proc 可以在下一个工作日返回我,即如果我在该 proc 中传递 41907 或 41908 或 41909 作为 DateID,它将在下一个工作日返回 41910.基本上我想检查当我传递上面的 EndDateID 时我的 proc 返回的 DateID 是否与上面数据中的下一个 StartDateID 相同,然后这两行都应该被打成棍子.下面是我想要获取的数据.

I already have another proc that can return me the next working day, i.e. if I pass 41907 or 41908 or 41909 as DateID in that proc, it will return 41910 as the next working day. Basically I want to check if the DateID returned by my proc when I pass the above EndDateID is same as the next StartDateID from above data, then both the rows should be clubbed. Below is the data I want to get.

ID          StartDate     EndDate    Duration 
----------
278457        41890       41892       3
278457        41898       41900       3
278457        41906       41910       3

如果要求不明确,请告诉我,我可以进一步解释.

Please let me know in case the requirement is not clear, I can explain further.

我的日期表如下:

DateId        Date      Day
----------
41906      09-04-2014    Thursday
41907      09-05-2014    Friday
41908      09-06-2014    Saturdat
41909      09-07-2014    Sunday
41910      09-08-2014    Monday

这是用于设置的 SQL 代码:

Here is the SQL Code for setup:

CREATE TABLE Table1
(
StartDate INT,
EndDate INT,
LeaveDuration INT
)

INSERT INTO Table1
VALUES(41890, 41892, 3),
(41898, 41900, 3),
(41906, 41907, 3),
(41910, 41910, 1)

CREATE TABLE DateTable
(
DateID INT,
Date DATETIME,
Day VARCHAR(20)
)

INSERT INTO DateTable
VALUES(41907, '09-05-2014', 'Friday'),
(41908, '09-06-2014', 'Saturday'),
(41909, '09-07-2014', 'Sunday'),
(41910, '09-08-2014', 'Monday'),
(41911, '09-09-2014', 'Tuesday')

推荐答案

这相当复杂.这是使用窗口函数的方法.

This is rather complicated. Here is an approach using window functions.

首先用日期表枚举没有周末的日期(如果你想也可以去掉假期).然后,使用非等值联接将期间扩展为每行一天.

First, use the date table to enumerate the dates without weekends (you can also take out holidays if you want). Then, expand the periods into one day per row, by using a non-equijoin.

然后,您可以使用一种技巧来确定连续的日子.这个技巧是为每个 id 生成一个序列号,然后从日期的序列号中减去它.这是连续天数的常数.最后一步只是一个聚合.

You can then use a trick to identify sequential days. This trick is to generate a sequential number for each id and subtract it from the sequential number for the dates. This is a constant for sequential days. The final step is simply an aggregation.

查询结果如下:

with d as (
      select d.*, row_number() over (order by date) as seqnum
      from dates d
      where day not in ('Saturday', 'Sunday')
     )
select t.id, min(t.date) as startdate, max(t.date) as enddate, sum(duration)
from (select t.*, ds.seqnum, ds.date,
             (d.seqnum - row_number() over (partition by id order by ds.date) ) as grp
      from table t join
           d ds
           on ds.date between t.startdate and t.enddate
     ) t
group by t.id, grp;

以下是这个 SQL Fiddle的版本:

The following is the version on this SQL Fiddle:

with d as (
      select d.*, row_number() over (order by date) as seqnum
      from datetable d
      where day not in ('Saturday', 'Sunday')
     )
select t.id, min(t.date) as startdate, max(t.date) as enddate, sum(duration)
from (select t.*, ds.seqnum, ds.date,
             (ds.seqnum - row_number() over (partition by id order by ds.date) ) as grp
      from (select t.*, 'abc' as id from table1 t) t join
           d ds
           on ds.dateid between t.startdate and t.enddate
     ) t
group by grp;

我相信这是有效的,但日期表中没有包含所有日期.

I believe this is working, but the date table doesn't have all the dates in it.

这篇关于为工作日俱乐部排行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

上一篇:如何在 SQL Server 中将自定义字符串转换为日期 下一篇:TSQL,帮助查询用户年龄

相关文章

最新文章