【问题标题】:3 Strikes Query SQL 20083 罢工查询 SQL 2008
【发布时间】:2016-09-16 01:09:11
【问题描述】:

我需要创建一个 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

它给出了以下输出。

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

【问题讨论】:

  • 应该比较哪一列来检查它是否属于absence start + 90 days?是AbsenceEnd吗?

标签: sql-server-2008 datediff


【解决方案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

【讨论】:

    猜你喜欢
    • 2015-07-13
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多