我需要根据错误在时间跨度中发生的次数对错误进行分类。 我做了一个“ A”,“ B”和“ C”类别,以指示错误发生的频率。如果错误发生的频率不足以符合“ A”,“ B”和“ C”的标准,那么我也具有“ Z”类别。 请注意,用户可以根据需要添加任意多个类别(“ D”,“ E”,“ F”等。)
我进行的查询几乎给出了正确的结果,但是我需要按条件顺序过滤掉“下游”的条件,因为某些错误将适合多个条件。
表格:
errors
ErrorNo ErrorName
1 'Error 1'
2 'Error 2'
3 'Error 3'
4 'Error 4'
errorLog
errorNo timestamp
1 2019-04-26 --1 time each day the last 6 days
1 2019-04-25
1 2019-04-24
1 2019-04-23
1 2019-04-22
1 2019-04-21
2 2019-04-26 --3 times today
2 2019-04-26
2 2019-04-26
3 2019-04-26
3 2019-03-26 --1 month ago
errorCategoryTypes
categoryName months minErrorCnt
A 1 6 --means at least 6 times the last 1 month
B 1 2 --means at least 2 times the last 1 month
C 3 1 --means at least 1 times the last 3 month
SQL查询:
select errors.errorNo
, case when category.categoryName is not null then category.categoryName else 'Z' end
from errors
left join (
select errorNo, categoryName
from errorLog
join errorCategoryTypes on errorLog.timestamp between DATEADD(day,-(errorCategoryTypes.months * 30),getdate()) and GETDATE()
group by errorNo, categoryName, errorCategoryTypes.minErrorCnt
having COUNT(errorLog.id) >= errorCategoryTypes.minErrorCnt
) category on errors.errorNo = category.errorNo
group by errors.errorNo, category.categoryName
它产生以下结果,因为“错误1”实际上符合所有“ A”,“ B”和“ C”标准,而“ B”同时符合“ B”和“ C”。但是,找到适合后如何停止计算呢?
ErrorNo Category
1 A
1 B
1 C
2 B
2 C
3 C
4 Z
我需要以下结果
ErrorNo Category
1 A --because error 1 occures at least 6 times during the last 1 month
2 B --because error 2 occures at least 2 times during the last 1 month
3 C --because error 3 occures at least 1 time during the last 3 months
4 Z --because error 4 does not fit A, B or C category criterias
答案 0 :(得分:0)
您可以使用窗口功能:
select e.errorno, e.categoryName
from (select e.errorno, e.categoryName,
count(*) as applicable_errors,
row_number() over (partition by e.errorno order by e.categoryName) as seqnum
from error e left join
errorlog el
on el.errorno = e.errorno left join
errorCategoryTypes ect
on el.timestamp >= dateadd(month, - ect.months, getdate())
group by e.errorno, e.categoryName, e.
having count(*) >= minErrorCnt
) e
where seqnum = 1;
注意:这必须依赖于类别名称进行订购。您应该在错误类型表
中有一个优先级列