我想获得大于 80 的所有值,排名,然后分组以获得阈值违规的计数

Pet*_*gun 3 t-sql sql-server-2008-r2

我在 MS SQL Server 2008R2 中有以下基本数据集:

create table #temptable
(
    Source varchar(255),
    PollTime datetime, 
    Value numeric(20,2)
)

insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 11:41:08.000' as datetime), 66)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 11:46:08.000' as datetime), 70)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 11:55:08.000' as datetime), 66)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:00:08.000' as datetime), 70)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:05:08.000' as datetime), 80)--1
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:11:08.000' as datetime), 81)--1
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:14:08.000' as datetime), 84)--1
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:20:08.000' as datetime), 70)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:22:08.000' as datetime), 60)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:26:08.000' as datetime), 62)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:34:08.000' as datetime), 63)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:40:08.000' as datetime), 80)--2
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:46:08.000' as datetime), 82)--2
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:49:08.000' as datetime), 90)--2
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:50:08.000' as datetime), 70)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 12:54:08.000' as datetime), 80)--3
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 13:01:08.000' as datetime), 80)--3
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 13:05:08.000' as datetime), 81)--3
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 13:10:08.000' as datetime), 63)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 13:15:08.000' as datetime), 64)
insert into #temptable( Source, PollTime, Value) values('ABC', cast('2015-01-03 13:20:08.000' as datetime), 65)
Run Code Online (Sandbox Code Playgroud)

我想对所有大于 80 的值应用一个块值,并将它们分组,以便我可以计算阈值违规。

到目前为止,我有以下 t-sql 代码:

Select      
    *
from
(
    Select 
        *,
        block = case 
                when Value >= 80 then
                    dense_rank() over (partition by Source order by PollTime)  
                    --dense_rank() over (partition by Source, Value order by PollTime)
                when Value < 80 then 0
            end     
    from #temptable
) as rankdata order by PollTime
Run Code Online (Sandbox Code Playgroud)

我得到以下返回数据:

Source  PollTime                Value   Block 
ABC     2015-01-03 11:41:08.000 66.00   0
ABC     2015-01-03 11:46:08.000 70.00   0
ABC     2015-01-03 11:55:08.000 66.00   0
ABC     2015-01-03 12:00:08.000 70.00   0
ABC     2015-01-03 12:05:08.000 80.00   5
ABC     2015-01-03 12:11:08.000 81.00   6
ABC     2015-01-03 12:14:08.000 84.00   7
ABC     2015-01-03 12:20:08.000 70.00   0
ABC     2015-01-03 12:22:08.000 60.00   0
ABC     2015-01-03 12:26:08.000 62.00   0
ABC     2015-01-03 12:34:08.000 63.00   0
ABC     2015-01-03 12:40:08.000 80.00   12
ABC     2015-01-03 12:46:08.000 82.00   13
ABC     2015-01-03 12:49:08.000 90.00   14
ABC     2015-01-03 12:50:08.000 70.00   0
ABC     2015-01-03 12:54:08.000 80.00   16
ABC     2015-01-03 13:01:08.000 80.00   17
ABC     2015-01-03 13:05:08.000 81.00   18
ABC     2015-01-03 13:10:08.000 63.00   0
ABC     2015-01-03 13:15:08.000 64.00   0
ABC     2015-01-03 13:20:08.000 65.00   0
Run Code Online (Sandbox Code Playgroud)

但是,我无法弄清楚以及我想要返回的合适数据集是:

Source  PollTime                Value   Block 
ABC     2015-01-03 11:41:08.000 66.00   0
ABC     2015-01-03 11:46:08.000 70.00   0
ABC     2015-01-03 11:55:08.000 66.00   0
ABC     2015-01-03 12:00:08.000 70.00   0
ABC     2015-01-03 12:05:08.000 80.00   1
ABC     2015-01-03 12:11:08.000 81.00   1
ABC     2015-01-03 12:14:08.000 84.00   1
ABC     2015-01-03 12:20:08.000 70.00   0
ABC     2015-01-03 12:22:08.000 60.00   0
ABC     2015-01-03 12:26:08.000 62.00   0
ABC     2015-01-03 12:34:08.000 63.00   0
ABC     2015-01-03 12:40:08.000 80.00   2
ABC     2015-01-03 12:46:08.000 82.00   2
ABC     2015-01-03 12:49:08.000 90.00   2
ABC     2015-01-03 12:50:08.000 70.00   0
ABC     2015-01-03 12:54:08.000 80.00   3
ABC     2015-01-03 13:01:08.000 80.00   3
ABC     2015-01-03 13:05:08.000 81.00   3
ABC     2015-01-03 13:10:08.000 63.00   0
ABC     2015-01-03 13:15:08.000 64.00   0
ABC     2015-01-03 13:20:08.000 65.00   0
Run Code Online (Sandbox Code Playgroud)

请记住,这只是我正在使用的示例数据集。这些值会改变,我的生产环境中也会有多个来源。(MS SQL Server 2008R2)

谢谢,皮特

spa*_*dba 5

这是一个仅使用排名函数的解决方案:

SELECT source, 
    polltime, 
    value, 
    block = 
        CASE -- ranks the islands
            WHEN Value >= 80 THEN DENSE_RANK() OVER (PARTITION BY source, CASE bb WHEN 0 THEN 0 ELSE 1 END ORDER BY bb )
            ELSE 0 
        END  
FROM (
    SELECT *,
        bb = -- creates the "islands"
            CASE 
                WHEN Value >= 80 THEN 
                    ROW_NUMBER() OVER(PARTITION BY source  ORDER BY polltime) - 
                    ROW_NUMBER() OVER(PARTITION BY source, CASE WHEN Value >= 80 THEN 1 ELSE 0 END ORDER BY polltime) + 1
                ELSE 0
            END
    FROM #temptable
) AS rankdata
ORDER BY polltime;
Run Code Online (Sandbox Code Playgroud)