我有一个服务的日志表,可以定期测量我的软件的各种指标。 (简化)表格如下:
+-------------------+--------+-----+
| ENTRYDATETIME| METRIC|VALUE|
|2018-01-16 12:30:00|MyMetric| 0|
|2018-01-16 13:00:00|MyMetric| 5|
|2018-01-16 13:30:00|MyMetric| 50|
|2018-01-16 14:00:00|MyMetric| 65|
|2018-01-16 14:30:00|MyMetric| 10|
|2018-01-16 15:00:00|MyMetric| 0|
|2018-01-16 15:30:00|MyMetric| 13|
|2018-01-16 16:00:00|MyMetric| 50|
|2018-01-16 16:30:00|MyMetric| 20|
|2018-01-16 17:00:00|MyMetric| 0|
+-------------------+--------+-----+
我需要一个查询来计算值字段中的数字超过40的次数,但是将连续次数计为单个事件。上表的结果应为2。
添加更多上下文:这是衡量服务等待处理的文件数量,我想测量一天中积压的出现次数。在上面的例子中,在14:00测量的积压是在13:30首次观察到的积压,所以我希望从任何结果中排除该记录。
我可以用光标一个接一个地循环遍历记录,但是我会尝试这种方法有很多不同的指标和标准,所以如果有更好的方法可以做到这一点有人指出我正确的方向吗?
答案 0 :(得分:3)
此查询应返回您的预期结果
select
count(distinct grp)
from (
select
*, rn1 - row_number() over (order by ENTRYDATETIME) grp
from (
select
*, row_number() over (order by ENTRYDATETIME) rn1
from
MyTable
) t
where
VALUE > 40
) t
答案 1 :(得分:2)
这是一个差距和岛屿问题
select count(*)
from
(
select exceed, grn
from
(
select *,
row_number() over (order by ENTRYDATETIME) -
row_number() over (partition by exceed order by ENTRYDATETIME) grn
from
(
select *,
case when value > 40 then 1 else 0 end exceed
from your_table
) t1
) t2
where exceed = 1
group by exceed, grn
) t3
神奇的是识别连续的序列。这是使用两个row_number()
函数实现的:第一个是全局的,第二个是每个组(在我的情况下超过)。差异允许您识别连续序列。
答案 2 :(得分:0)
假设结果返回2就足够了,这就是我会这样做的方式,但我不相信这是你需要的,因为它是如此基本以及你提到游标的事实。 GroupCTE只将两个值组合在一起,并返回两行,您可以使用count rows函数
来计算WITH GroupCTE AS
(
SELECT Metric,Value
FROM Tablename
WHERE VALUE > 40
AND METRIC = 'MyMetric'
GROUP BY METRIC,VALUE
)
SELECT COUNT(*)
FROM GroupCTE
答案 3 :(得分:0)
使用lag
函数的另一个选项;检查该值是否超过40且其先前值<= 40,在这种情况下将其计为1:
;with lag_t as(
select
value,
lag(value,1,0) over (order by ENTRYDATETIME) as l_value
from t
)
select
sum(case when value > 40 and l_value <= 40 then 1 else 0 end) as cnt
from lag_t;