好的,我有一个严格的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对并添加,如果是这样,也添加这些天。我已经可以告诉我,这不是我想要使用的方法,但我无法完全理解我需要如何开始/构建此查询。有没有人有想法可以引导我朝着正确的方向前进?我意识到这可能不太清楚,如果我只是让事情混乱,我道歉。
答案 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天”。