查找一系列日期间隔的总持续时间

时间:2013-08-30 16:41:48

标签: sql sql-server-2008 sql-server-2008-r2

我有一个包含工作列表的数据库;例如,它可以是简历中以前的工作经历列表。 我想知道一个人受雇多少天;所以,我写了这个查询:

SELECT sum(datediff(dd,isnull(date_begin,getdate()),isnull(date_end,getdate()))+1)
  FROM jobs
 WHERE person_id=X

问题是,有时这些日期重叠。例如:

person date_from   date_to     Comment
John   01-Jan-2011 31-Dec-2012 Two years working at ABC
John   01-Jan-2012 31-Dec-2013 Two years of extra work at evening

在这种情况下,我的查询将返回4年,但我只想返回3.换句话说,如果一个人有一年的2个工作,我希望它计为1年,而不是2年。重叠的工作可以是任何数字,而不仅仅是2。 我尝试通过减去所有重叠的总持续时间来调整查询,这对于2个重叠的作业很有效,但如果有更多的话,这将失败。

2 个答案:

答案 0 :(得分:2)

您可以使用cte制作日期的驱动程序列表,然后JOIN使用BETWEEN来获取不同的日期,如果此查询经常运行,则可能值得使用cte创建一个日期查找表并为其编制索引:

;WITH cte AS (SELECT CAST('20100101' AS DATE) 'Dt'
              UNION ALL
              SELECT DATEADD(DAY,1,Dt)
              FROM cte
              WHERE dt <= GETDATE())   
SELECT person,MIN(b.dt),MAX(b.Dt),COUNT(DISTINCT b.dt)'Total Days'
FROM #Table a
JOIN cte b
  ON b.Dt BETWEEN a.date_from AND a.date_to            
GROUP BY person
OPTION (MAXRECURSION 0)   

答案 1 :(得分:1)

我能想到的一种方法是创建一个临时表来保持每天在开始和结束日期之间工作。然后,您将创建一个游标来遍历员工的每条记录(每个唯一的就业条目),并将所有工作日添加到临时表(Get a list of dates between two dates using a function的示例)。

如果您的表格已加载所有工作日,请在列表中选择不同日期的计数。