我正在寻找针对以下问题的SQL解决方案。 我想要一份超过14天连续生病的员工名单。
我有一个包含以下内容的SQL表:
First_name, Last_Name, INDIRECT_ID, SHIFT_DATE
John, Doe, Sick, 2016-01-01
John, Doe, Sick, 2016-01-02
John, Doe, working, 2016-01-03
John, Doe, Sick, 2016-01-04
John, Doe, Sick, 2016-01-05
etc.
我想通过观察他们是否在两周内生病10x(2x5个工作日)来做到这一点。但也许有一个更简单的解决方案。但现在我也得到了重复的答案。
select FIRST_NAME, LAST_NAME
from (select t.*
,(select count(*)
from LABOR_TICKET t2
where t2.EMPLOYEE_ID = t.EMPLOYEE_ID and
t2.INDIRECT_ID = t.INDIRECT_ID and
t2.SHIFT_DATE >= t.SHIFT_DATE and
t2.SHIFT_DATE < DATEADD(day, 14, t.SHIFT_DATE)) NumWithin14Days
from LABOR_TICKET t
where SHIFT_DATE between '2016-01-01' and '2016-04-01'
) LABOR_TICKET
INNER JOIN
EMPLOYEE ON LABOR_TICKET.EMPLOYEE_ID = EMPLOYEE.ID
where NumWithin14Days >= 10 AND INDIRECT_ID = 'SICK'
答案 0 :(得分:0)
试试这个, 首先在From Date和To Date之间创建所有14天的间隔。 然后检查每个员工每个时间间隔内“生病”的计数是14。
DECLARE @ST_DATE DATE='2016-01-01'
,@ED_DATE DATE='2016-04-01'
;WITH CTE_DATE AS (
SELECT @ST_DATE AS ST_DATE,DATEADD(DAY,13,@ST_DATE) AS ED_DATE
UNION ALL
SELECT DATEADD(DAY,1,ED_DATE),DATEADD(DAY,14,ED_DATE)
FROM CTE_DATE
WHERE DATEADD(DAY,14,ED_DATE) <= @ED_DATE
)
SELECT FIRST_NAME, LAST_NAME
FROM CTE_DATE
INNER JOIN LABOR_TICKET ON SHIFT_DATE BETWEEN ST_DATE AND ED_DATE
WHERE INDIRECT_ID = 'Sick'
GROUP BY FIRST_NAME, LAST_NAME
HAVING COUNT(*) >= 14
答案 1 :(得分:0)
伪代码,为您提供所有员工的想法
如果你有一个如下所示的日历表
onSelectDate
现在你可以将你的主表连接到
create table dates
(
datetime date
)
insert into dates
select '2016-01-01'
union all
select '2016-01-02'
答案 2 :(得分:0)
你应该抛出更多样本数据。
试试这个,(我相信它可以与其他样本数据一起使用)很少有东西可以过滤数据。
declare @t table(First_name varchar(50), Last_Name varchar(50), INDIRECT_ID varchar(50), SHIFT_DATE date)
insert into @t values
('John', 'Doe', 'Sick', '2016-01-01')
,('John', 'Doe', 'Sick', '2016-01-02')
,('John','Doe','working','2016-01-03')
,('John', 'Doe', 'Sick', '2016-01-04')
,('John', 'Doe', 'Sick', '2016-01-05')
declare @name varchar(50)='John'
declare @month int=1
;With CTE as
(
select top 1 First_name,Last_Name,SHIFT_DATE,1 rn from @T where First_name=@name
and INDIRECT_ID='Sick' order by SHIFT_DATE
union all
select t.First_name,t.Last_Name,t.SHIFT_DATE, rn+1 from @T t
inner join cte c on t.First_name=c.First_name
where INDIRECT_ID='Sick'
and t.SHIFT_DATE=DATEADD(day,1,c.SHIFT_DATE)
and t.SHIFT_DATE<='2016-01-31'
)
select * from CTE where rn>=14
答案 3 :(得分:0)
declare @t table(First_name varchar(50), Last_Name varchar(50), INDIRECT_ID varchar(50), SHIFT_DATE date)
insert into @t values
('John', 'Doe', 'Sick', '2016-01-01')
,('John', 'Doe', 'Sick', '2016-01-02')
,('John','Doe','working','2016-01-03')
,('John', 'Doe', 'Sick', '2016-04-04')
,('John', 'Doe', 'Sick', '2016-05-05')
select s.*
,u.*
,Sickdays =
case
when s.indirect_id = 'Sick' and u.indirect_id = 'Sick' then datediff(dd,u.shift_date,s.shift_date)
else 0
end
from
(
select t.*,
row_number() over(partition by last_name,first_name order by shift_date desc) rn
from @t t
) s
join
(select t.*,
row_number() over(partition by last_name,first_name order by shift_date desc) rn
from @t t
) u on s.last_name = u.last_name and s.first_name = u.first_name and s.rn = u.rn - 1
where
case
when s.indirect_id = 'Sick' and u.indirect_id = 'Sick' then datediff(dd,u.shift_date,s.shift_date)
else 0
end > 13