SQL Query X Days back不包括日期范围(令人困惑!)

时间:2014-06-25 00:12:04

标签: sql sql-server

好的,我有一个严格的SQL查询,而且我不确定如何编写它。

我总结了过去X天内员工收集的“香蕉”的数量,但我真正可以使用的帮助是确定 X

“过去X天”值定义为员工因为紫热病而 NOT 的最后100天,从某些{{1}开始(我们今天会说,2014年6月24日)。也就是说,如果这个人患有紫热病3天,那么我想回顾过去103天ChosenDate而不是过去100天。员工可能已经离开的任何其他原因不会影响我们的计算。

ChosenDate

表格已经建立。许多Table PersonOutIncident +----------------------+----------+-------------+ | PersonOutIncidentID | PersonID | ReasonOut | +----------------------+----------+-------------+ | 1 | Sarah | PurpleFever | | 2 | Sarah | PaperCut | | 3 | Jon | PurpleFever | | 4 | Sarah | PurpleFever | +----------------------+----------+-------------+ Table PersonOutDetail +-------------------+----------------------+-----------+-----------+ | PersonOutDetailID | PersonOutIncidentID | BeginDate | EndDate | +-------------------+----------------------+-----------+-----------+ | 1 | 1 | 1/1/2014 | 1/3/2014 | | 2 | 1 | 1/7/2014 | 1/13/2014 | | 3 | 2 | 2/1/2014 | 2/3/2014 | | 4 | 3 | 1/15/2014 | 1/20/2014 | | 5 | 4 | 5/1/2014 | 5/15/2014 | +-------------------+----------------------+-----------+-----------+ 条记录可以与一条PersonOutDetail条记录相关联,并且单个员工可能有多条PersonOutIncident条记录(也就是说,可能有两个或三条PersonOutIncident条记录具有相同PersonOutIncident列的记录,因为它们代表特定事件或事件,并且由于该特定事件而不一定连续几天丢失)

这个要求的性质使事情变得复杂,甚至在概念上也是如此。

我能想到的最好的方法是在100天基期内检查ReasonOut / BeginDate对,然后确定从EndDate到{{1}的天数并将其添加到基地100天。但是我必须再次检查这个新范围是否重叠或包含额外的BeginDate / EndDate对并添加,如果是这样,也添加这些天。我已经可以告诉我,这不是我想要使用的方法,但我无法完全理解我需要如何开始/构建此查询。有没有人有想法可以引导我朝着正确的方向前进?我意识到这可能不太清楚,如果我只是让事情混乱,我道歉。

1 个答案:

答案 0 :(得分:0)

执行此操作的一种方法是使用包含天数列表的表或WITH CLAUSE。假设days是一个包含最后200天的列的表。 (这意味着如果员工在过去200天内的病假超过100天,查询将会中断。)

现在,您可以获取此类员工的所有工作日列表(将?替换为员工ID):

WITH t1 AS
(
    SELECT day,
           ROW_NUMBER() OVER (ORDER BY day DESC) AS 'RowNumber'
    FROM days d
    WHERE NOT EXISTS (SELECT * FROM PersonOutDetail pd
          INNER JOIN PersonOutIncidentID po ON po.PersonOutIncidentID = pd.PersonOutIncidentID
          WHERE d.day BETWEEN pd.BeginDate AND pd.EndDate
          AND po.ReasonOut = 'PurpleFever'
          AND po.PersonID = ?)
)
SELECT * FROM t1
WHERE RowNumber <= 100;

或者,您可以将RowNumber <= 100替换为RowNumber = 100来获取“第100天”。