员工有10天缺席。
以下是我的数据。
我需要FromDate(the Date Start Absent)
和ToDate(the Date End Absent)
条件将是这样的
if the 10 days Continuous where STATUS='A' Included STATUS='R'
供参考:
'A'缺席
'R'为RestDay
'L'为离开
DECLARE @SomeTable TABLE ([EmpId] INT,[Date] DATETIME,[STATUS] char(1))
--YOUR SAMPLE DATA
INSERT INTO @SomeTable
([EmpId],[Date],[STATUS])
SELECT 999,'2016-07-11 00:00:00.000','A'
UNION SELECT 999,'2016-07-10 00:00:00.000','A'
UNION SELECT 999,'2016-07-09 00:00:00.000','R'
UNION SELECT 999,'2016-07-08 00:00:00.000','R'
UNION SELECT 999,'2016-07-07 00:00:00.000','A'
UNION SELECT 999,'2016-07-06 00:00:00.000','A'
UNION SELECT 999,'2016-07-05 00:00:00.000','A'
UNION SELECT 999,'2016-07-04 00:00:00.000','A'
UNION SELECT 999,'2016-07-03 00:00:00.000','A'
UNION SELECT 999,'2016-07-02 00:00:00.000','R'
UNION SELECT 999,'2016-07-01 00:00:00.000','R'
UNION SELECT 999,'2016-06-30 00:00:00.000','A'
UNION SELECT 999,'2016-06-29 00:00:00.000','A'
UNION SELECT 999,'2016-06-28 00:00:00.000','A'
UNION SELECT 999,'2016-06-27 00:00:00.000','L'
UNION SELECT 999,'2016-06-26 00:00:00.000','A'
UNION SELECT 999,'2016-06-25 00:00:00.000','R'
SELECT * FROM @SomeTable
我想得到以下输出:
EmpId FromDate ToDate
999 2016-06-28 00:00:00.000 2016-07-11 00:00:00.000
答案 0 :(得分:3)
您可以使用以下查询:
SELECT EmpId,
MAX(CASE WHEN rn = 1 THEN [Date] END) AS FromDate,
MAX(CASE WHEN rn = 10 THEN [Date] END) AS ToDate
FROM (
SELECT EmpId, [Date], STATUS, grp,
ROW_NUMBER() OVER (PARTITION BY EmpId, STATUS, grp
ORDER BY [Date]) AS rn
FROM (
SELECT EmpId, [Date], STATUS,
ROW_NUMBER() OVER (PARTITION BY EmpId ORDER BY [Date]) -
ROW_NUMBER() OVER (PARTITION BY EmpId, STATUS
ORDER BY [Date]) AS grp
FROM @SomeTable
WHERE STATUS <> 'R') AS t) AS s
GROUP BY EmpId, STATUS, grp
HAVING COUNT(*) >= 10
修改强>
如果要求连续记录切片的总数等于或大于'A'
,则要求任意个连续10
个记录,查询可以大大简化为:
SELECT EmpId,
MIN([Date]) AS FromDate,
MAX([Date]) AS ToDate
FROM (
SELECT EmpId, [Date], STATUS,
ROW_NUMBER() OVER (PARTITION BY EmpId ORDER BY [Date]) -
ROW_NUMBER() OVER (PARTITION BY EmpId, STATUS ORDER BY [Date]) AS grp
FROM @SomeTable
WHERE STATUS <> 'R') AS t
GROUP BY EmpId, STATUS, grp
HAVING COUNT(*) >= 10
答案 1 :(得分:0)
我不知道我是否完全理解,但我认为最简单的方法是计算STATUS
不 A或R的出现次数。
以下查询列表计算10天后有多少非A-or-R 行。所有零行都有10天的差距。
SELECT *
,tbl.[Date]-10 AS TenDaysBack
,(SELECT COUNT(*)
FROM @SomeTable AS x
WHERE x.EmpId=tbl.EmpId
AND x.[Date]>=tbl.[Date]-10
AND x.[Date]<=tbl.[Date]
AND x.STATUS NOT IN('A','R')
)
FROM @SomeTable AS tbl
ORDER BY tbl.[Date]
答案 2 :(得分:0)
; with cte as
(
SELECT r = row_number() over (partition by EmpId order by Date),
EmpId, Date, stat = case when STATUS in ('A', 'R') then 1 else 0 end
FROM @SomeTable t
),
cte2 as
(
select *, g = r - dense_rank() over (partition by stat order by r)
from cte
)
select EmpId, FrDate = min(Date), ToDate = max(Date), Cnt = count(*)
from cte2
where stat = 1
group by EmpId, g
having count(*) >= 10