2013-08-30 59 views
0

我有一个包含作业列表的数据库;例如,它可能是CV中以前工作经历的列表。 我想知道一个人被雇用多少天;所以,我写了这个查询:查找一系列日期间隔的总持续时间

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个重叠的工作很合适,但如果有更多的工作,这将失败。

+0

虽然解决方案可以是任何语言,但我的计划是创建一个SQL函数,所以我更喜欢纯SQL。 –

+0

你使用哪个sql引擎? MySQL的? SQL Server?仅在sql中可能会很复杂。 – csg

+0

SQL Server 2008 r2 –

回答

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

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

将表格加载到所有工作日后,选择列表中不同天数的计数。