使用查询分组和检查条件
Grouping and checking for conditions using a query
我被要求为以下情况编译一个 SQL 查询:
ID | PARAMETER | VALID | VALUE
------------------------------
1 | Event1_Val | 1 | 0
1 | Event2_Val | 0 | 50.00
1 | Event2_Avg | 0 | 55.00
1 | Event1_Avg | 0 | 66.67
2 | Event1_Val | 0 | 37.50
2 | Event2_Val | 1 | 0
2 | Event1_Avg | 0 | 50.00
2 | Event2_Avg | 0 | 66.67
其中 _Val
是当前值。 _Avg
是过去五个值的平均值。
要求1:如果VALID == 1
(仅适用于_Val
值),不检查该参数的_Val
和_Avg
,但检查其他参数的 _Val
和 _Avg
。在上面的示例中,ID=1
、Event2_Val
和 Event2_Avg
将被检查,因为 Event1_Val.VALID = 1
(这意味着 Event1_Val
和 Event1_Avg
不会被检查。 )
要求 2: 检查 _Val
和 _Avg
的值作为以下条件的要求 1 的结果:
_Val
< 5 或
_Val
+ 10 < _Avg
上述条件 return 警报。在上面 ID=2
的示例中,Event1_Val
将 return 发出警报,因为 37.50 + 10 小于 50.00。
需求三:说明需求二的结果
ID | PARAMETER | ALERT
------------------------
1 | Event2_Val | 0
2 | Event1_Val | 1
我已尝试检查 VALID
是否不等于 1,但结果如下:
ID | PARAMETER | VALID | VALUE
------------------------------
1 | Event2_Val | 0 | 50.00
1 | Event2_Avg | 0 | 55.00
1 | Event1_Avg | 0 | 66.67
2 | Event1_Val | 0 | 37.50
2 | Event1_Avg | 0 | 50.00
2 | Event2_Avg | 0 | 66.67
我不想检查 _Val.VALID == 1
事件的参数。意思是,对于 ID=1
,我不想包括 Event1_Avg
。
对于这种情况,有没有办法使用查询来分组和检查条件? 注意:强烈希望不要更改表中的值。
尝试:
SELECT t1.id,
t1.parameter,
CASE
WHEN (t1.value < 5 OR (t1.value + 10 < t2.value)) THEN 1
ELSE 0
END alert
FROM your_table t1
JOIN your_table t2 ON t1.id = t2.id
AND left(t1.parameter, 6) = left(t2.parameter, 6)
AND t1.parameter LIKE '%_Val'
AND t2.parameter LIKE '%_Avg'
WHERE
t1.valid <> 1
给你,一些解释发生了什么的评论:
declare @events table
(
ID int
,PARAMETER nvarchar(25)
,VALID bit
,VALUE decimal (18,2)
)
insert into @events(ID, PARAMETER,VALID, VALUE)
select 1 , 'Event1_Val' , 1 , 0
union all
select 1 , 'Event2_Val' , 0 , 50.00
union all
select 1 , 'Event2_Avg' , 0 , 55.00
union all
select 1 , 'Event1_Avg' , 0 , 66.67
union all
select 2 , 'Event1_Val' , 0 , 37.50
union all
select 2 , 'Event2_Val' , 1 , 0
union all
select 2 , 'Event1_Avg' , 0 , 50.00
union all
select 2 , 'Event2_Avg' , 0 , 66.67
select * from @events e
SELECT
ID
,PARAMETER
,CASE WHEN (VALUE < 5 OR VALUE + 10.00 < AVRG) THEN 1 ELSE 0 END AS ALERT
FROM
(
select
e.ID,
MAX(CASE WHEN RIGHT(e.PARAMETER,4) = '_Val' THEN e.PARAMETER END ) as PARAMETER,
MAX(CASE WHEN RIGHT(e.PARAMETER,4) = '_Val' THEN e.VALUE END) as VALUE,
MAX(CASE WHEN RIGHT(e.PARAMETER,4) = '_Avg' THEN e.VALUE END) as AVRG
from @events e
JOIN
( --Get Valid Events
select ID, REPLACE(REPLACE(PARAMETER,'_Val',''),'_Avg','') as Parameter --returns EventNAme without '_Val' or '_Avg' for grouping porpuses
from @events
WHERE RIGHT(PARAMETER,4) = '_Val' and VALID = 0
GROUP BY ID ,REPLACE(REPLACE(PARAMETER,'_Val',''),'_Avg','')
) validEvents --filter by valid events only
on validEvents.ID = e.ID
AND validEvents.Parameter = REPLACE(REPLACE(e.PARAMETER,'_Val',''),'_Avg','')
GROUP BY e.ID
) PIVOTEDRESULTS
我被要求为以下情况编译一个 SQL 查询:
ID | PARAMETER | VALID | VALUE
------------------------------
1 | Event1_Val | 1 | 0
1 | Event2_Val | 0 | 50.00
1 | Event2_Avg | 0 | 55.00
1 | Event1_Avg | 0 | 66.67
2 | Event1_Val | 0 | 37.50
2 | Event2_Val | 1 | 0
2 | Event1_Avg | 0 | 50.00
2 | Event2_Avg | 0 | 66.67
其中 _Val
是当前值。 _Avg
是过去五个值的平均值。
要求1:如果VALID == 1
(仅适用于_Val
值),不检查该参数的_Val
和_Avg
,但检查其他参数的 _Val
和 _Avg
。在上面的示例中,ID=1
、Event2_Val
和 Event2_Avg
将被检查,因为 Event1_Val.VALID = 1
(这意味着 Event1_Val
和 Event1_Avg
不会被检查。 )
要求 2: 检查 _Val
和 _Avg
的值作为以下条件的要求 1 的结果:
_Val
< 5 或_Val
+ 10 <_Avg
上述条件 return 警报。在上面 ID=2
的示例中,Event1_Val
将 return 发出警报,因为 37.50 + 10 小于 50.00。
需求三:说明需求二的结果
ID | PARAMETER | ALERT
------------------------
1 | Event2_Val | 0
2 | Event1_Val | 1
我已尝试检查 VALID
是否不等于 1,但结果如下:
ID | PARAMETER | VALID | VALUE
------------------------------
1 | Event2_Val | 0 | 50.00
1 | Event2_Avg | 0 | 55.00
1 | Event1_Avg | 0 | 66.67
2 | Event1_Val | 0 | 37.50
2 | Event1_Avg | 0 | 50.00
2 | Event2_Avg | 0 | 66.67
我不想检查 _Val.VALID == 1
事件的参数。意思是,对于 ID=1
,我不想包括 Event1_Avg
。
对于这种情况,有没有办法使用查询来分组和检查条件? 注意:强烈希望不要更改表中的值。
尝试:
SELECT t1.id,
t1.parameter,
CASE
WHEN (t1.value < 5 OR (t1.value + 10 < t2.value)) THEN 1
ELSE 0
END alert
FROM your_table t1
JOIN your_table t2 ON t1.id = t2.id
AND left(t1.parameter, 6) = left(t2.parameter, 6)
AND t1.parameter LIKE '%_Val'
AND t2.parameter LIKE '%_Avg'
WHERE
t1.valid <> 1
给你,一些解释发生了什么的评论:
declare @events table
(
ID int
,PARAMETER nvarchar(25)
,VALID bit
,VALUE decimal (18,2)
)
insert into @events(ID, PARAMETER,VALID, VALUE)
select 1 , 'Event1_Val' , 1 , 0
union all
select 1 , 'Event2_Val' , 0 , 50.00
union all
select 1 , 'Event2_Avg' , 0 , 55.00
union all
select 1 , 'Event1_Avg' , 0 , 66.67
union all
select 2 , 'Event1_Val' , 0 , 37.50
union all
select 2 , 'Event2_Val' , 1 , 0
union all
select 2 , 'Event1_Avg' , 0 , 50.00
union all
select 2 , 'Event2_Avg' , 0 , 66.67
select * from @events e
SELECT
ID
,PARAMETER
,CASE WHEN (VALUE < 5 OR VALUE + 10.00 < AVRG) THEN 1 ELSE 0 END AS ALERT
FROM
(
select
e.ID,
MAX(CASE WHEN RIGHT(e.PARAMETER,4) = '_Val' THEN e.PARAMETER END ) as PARAMETER,
MAX(CASE WHEN RIGHT(e.PARAMETER,4) = '_Val' THEN e.VALUE END) as VALUE,
MAX(CASE WHEN RIGHT(e.PARAMETER,4) = '_Avg' THEN e.VALUE END) as AVRG
from @events e
JOIN
( --Get Valid Events
select ID, REPLACE(REPLACE(PARAMETER,'_Val',''),'_Avg','') as Parameter --returns EventNAme without '_Val' or '_Avg' for grouping porpuses
from @events
WHERE RIGHT(PARAMETER,4) = '_Val' and VALID = 0
GROUP BY ID ,REPLACE(REPLACE(PARAMETER,'_Val',''),'_Avg','')
) validEvents --filter by valid events only
on validEvents.ID = e.ID
AND validEvents.Parameter = REPLACE(REPLACE(e.PARAMETER,'_Val',''),'_Avg','')
GROUP BY e.ID
) PIVOTEDRESULTS