3 Strikes Query SQL 2008

时间:2016-05-19 08:54:27

标签: sql-server-2008 datediff

我需要创建一个SQL查询,当有人在3个月内达到3次或更多次时填充表。

我可以获得的数据是:

SELECT 'John Doe' AS Name, 1406 AS InstanceID, '2016-01-08 00:00:00.000' AS AbsenceStart, '2016-01-13 00:00:00.000' AS AbsenceEnd, 4 AS NoOfDays, 1 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1493 AS InstanceID, '2016-02-02 00:00:00.000' AS AbsenceStart, '2016-02-05 00:00:00.000' AS AbsenceEnd, 4 AS NoOfDays, 2 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1536 AS InstanceID, '2016-02-19 00:00:00.000' AS AbsenceStart, '2016-02-22 00:00:00.000' AS AbsenceEnd, 2 AS NoOfDays, 3 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1547 AS InstanceID, '2016-02-26 00:00:00.000' AS AbsenceStart, '2016-03-10 00:00:00.000' AS AbsenceEnd, 10 AS NoOfDays, 4 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1660 AS InstanceID, '2016-04-04 00:00:00.000' AS AbsenceStart, '2016-04-04 00:00:00.000' AS AbsenceEnd, 0.5 AS NoOfDays, 5 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1666 AS InstanceID, '2016-04-07 00:00:00.000' AS AbsenceStart, '2016-04-14 00:00:00.000' AS AbsenceEnd, 6 AS NoOfDays, 6 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1698 AS InstanceID, '2016-04-27 00:00:00.000' AS AbsenceStart, '2016-04-28 00:00:00.000' AS AbsenceEnd, 1 AS NoOfDays, 7 AS rnk

其中给出了以下输出。

enter image description here

我需要设计一个查询,该查询将在90天内有超过3个实例时进行标记。因此,在上述日期1406,1493,1536,1547,1660,1666将全部标记(历史上)。理想情况下,查询将每天运行,并在记录第3个实例后立即设置警报。我已经尝试了各种DATEDIFF和派生的查询,但似乎无法让它工作。 因此,期望的输出将是上表,但仅限于在第一次缺席开始+ 90天的日期范围内的那些。我知道我错过了一些简单的事情!

1 个答案:

答案 0 :(得分:1)

您可以通过循环执行此操作,请参阅下面的代码(已注释)。我把你的初始数据放到了#temp:

if object_id('tempdb..#temp') is not null
drop table #temp

SELECT 'John Doe' AS Name, 1406 AS InstanceID, '2016-01-08 00:00:00.000' AS 

AbsenceStart, '2016-01-13 00:00:00.000' AS AbsenceEnd, 4 AS NoOfDays, 1 AS rnk
into #temp
UNION ALL
SELECT 'John Doe' AS Name, 1493 AS InstanceID, '2016-02-02 00:00:00.000' AS AbsenceStart, '2016-02-05 00:00:00.000' AS AbsenceEnd, 4 AS NoOfDays, 2 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1536 AS InstanceID, '2016-02-19 00:00:00.000' AS AbsenceStart, '2016-02-22 00:00:00.000' AS AbsenceEnd, 2 AS NoOfDays, 3 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1547 AS InstanceID, '2016-02-26 00:00:00.000' AS AbsenceStart, '2016-03-10 00:00:00.000' AS AbsenceEnd, 10 AS NoOfDays, 4 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1660 AS InstanceID, '2016-04-04 00:00:00.000' AS AbsenceStart, '2016-04-04 00:00:00.000' AS AbsenceEnd, 0.5 AS NoOfDays, 5 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1666 AS InstanceID, '2016-04-07 00:00:00.000' AS AbsenceStart, '2016-04-14 00:00:00.000' AS AbsenceEnd, 6 AS NoOfDays, 6 AS rnk
UNION ALL
SELECT 'John Doe' AS Name, 1698 AS InstanceID, '2016-04-27 00:00:00.000' AS AbsenceStart, '2016-04-28 00:00:00.000' AS AbsenceEnd, 1 AS NoOfDays, 7 AS rnk


-- First find the start rank:
declare @x int = (select top 1 rnk from #temp order by rnk asc)
-- Find the maximum number of records to loop through
declare @y int = (select top 1 rnk from #temp order by rnk desc)
-- This is your threshold for publishing
declare @a int

-- start loop
while @x <= @y


begin

if @a >=3
break; -- if threshold breached, stop loop.

else    

if object_id('tempdb..#list') is not null
drop table #list

declare @z datetime = (select AbsenceStart from #temp where rnk = @x)
print @z

select
instanceid,
AbsenceStart
into #list
from #temp
where AbsenceStart >= @z
and AbsenceStart <= dateadd(dd,90,@z)


set @a = (select count(instanceid) from #list)



set @x = @x + 1

print @x

end

insert into dbo.DestinationTable
select * 
from #list