评估几个表达式,当为真时继续下一个 id
Evaluate several expression, continue to next id when true
我有 2 个 SQL 表,如下所示:
1.Noise
Noise_Id
Value
2
73
7
57
8
78
12
86
14
89
2。颜色
|ColorInt |Criteria |SortOrder|
|---------|---------------|---------|
|-1 | [Value] < 75 | 75 |
|-16711936| [Value] < 80 | 80 |
|-128 | [Value] < 85 | 85 |
|-10496 | [Value] < 90 | 90 |
|-23296 | [Value] < 95 | 95 |
|-65536 | [Value] < 100 | 100 |
|-38476 | [Value] < 105 | 105 |
|-8388480 | [Value] < 110 | 110 |
|-11861886| [Value] >= 110| 111 |
此 [Criteria] 列可以包含其他表达式,例如:
[Value]=1
[Value]=2
[Value]=3
[Value]=4
[Value]=5
FindingsCnt_Overdue > 0
FindingsCnt_Completed = FindingsCnt - FindingsCnt_Deleted
[Value] = -1
[Value] < 30
[Value] < 50
[Value] < 70
[Value] < 90
[Value] < 110
[Value] < 150
[Value] >= 150
我想根据 [Criteria] 为每个 [Noise_Id] 计算 [ColorInt],如下所示:
预期结果
Noise_Id
Value
ColorInt
2
73
-1
7
57
-1
8
78
-16711936
12
86
-10496
14
89
-10496
我如何创建一个高效的存储过程或函数来评估每个 [Noise_Id] 的 [Criteria] 列中的表达式,并在 [Criteria] 时转到下一个 [Noise_Id] ] 遇见了吗?
这是我试过的代码:
CREATE TABLE #Results (
Noise_Id int,
Value varchar(MAX))
DECLARE @SQL varchar(MAX)=''
SELECT @SQL =
@SQL+' Insert Into #Results(Noise_Id, Value) Select '+cast(Noise_Id AS varchar(50))+', case when '+Replace([Criteria],'[Value]',Value)+' then [ColorInt] else null end as Value FROM [Noise] where Noise_Id = '+cast(Noise_Id AS varchar(50))
FROM [Noise]
exec (@sql)
select * from #Results
drop table #Results
非常感谢您的帮助!
您需要将 Criteria
分成单独的列:Op
定义应该比较的内容,Criteria
定义要比较的值。
然后您可以分别与每个可能的运算符进行比较。
之后,每个组查询只是一个简单的 TOP 1
。
SELECT
n.Noise_Id
n.[Value],
c.ColorInt
FROM Noise n
CROSS APPLY (
SELECT TOP 1 c.ColorInt
FROM Color c
WHERE
(c.Op = '<' AND n.[Value] < c.Criteria) OR
(c.Op = '<=' AND n.[Value] <= c.Criteria) OR
(c.Op = '=' AND n.[Value] = c.Criteria) OR
(c.Op = '>' AND n.[Value] > c.Criteria) OR
(c.Op = '>=' AND n.[Value] >= c.Criteria)
ORDER BY c.SortOrder
) c
你说你不能修改 Criteria
列。那我们就得自己拆分了。
我假设 Value
总是在开头,比较器在中间,并且有空格。否则会失败。
SELECT
n.Noise_Id
n.[Value],
c.ColorInt
FROM Noise n
CROSS APPLY (
SELECT TOP 1 c.ColorInt
FROM Color c
CROSS APPLY (VALUES (
CAST(RIGHT(c.Criteria, CHARINDEX(' ', REVERSE(c.Criteria)) - 1) AS int) -- same data type as n.Value
) ) v(CriteriaNum)
WHERE
(c.Criteria LIKE '%<%' AND n.[Value] < v.CriteriaNum) OR
(c.Criteria LIKE '%<=%' AND n.[Value] <= v.CriteriaNum) OR
(c.Criteria LIKE '%=%' AND n.[Value] = v.CriteriaNuma) OR
(c.Criteria LIKE '%>%' AND n.[Value] > v.CriteriaNum) OR
(c.Criteria LIKE '%>=%' AND n.[Value] >= v.CriteriaNum)
ORDER BY c.SortOrder
) c
我有 2 个 SQL 表,如下所示:
1.Noise
Noise_Id | Value |
---|---|
2 | 73 |
7 | 57 |
8 | 78 |
12 | 86 |
14 | 89 |
2。颜色
|ColorInt |Criteria |SortOrder|
|---------|---------------|---------|
|-1 | [Value] < 75 | 75 |
|-16711936| [Value] < 80 | 80 |
|-128 | [Value] < 85 | 85 |
|-10496 | [Value] < 90 | 90 |
|-23296 | [Value] < 95 | 95 |
|-65536 | [Value] < 100 | 100 |
|-38476 | [Value] < 105 | 105 |
|-8388480 | [Value] < 110 | 110 |
|-11861886| [Value] >= 110| 111 |
此 [Criteria] 列可以包含其他表达式,例如:
[Value]=1
[Value]=2
[Value]=3
[Value]=4
[Value]=5
FindingsCnt_Overdue > 0
FindingsCnt_Completed = FindingsCnt - FindingsCnt_Deleted
[Value] = -1
[Value] < 30
[Value] < 50
[Value] < 70
[Value] < 90
[Value] < 110
[Value] < 150
[Value] >= 150
我想根据 [Criteria] 为每个 [Noise_Id] 计算 [ColorInt],如下所示:
预期结果
Noise_Id | Value | ColorInt |
---|---|---|
2 | 73 | -1 |
7 | 57 | -1 |
8 | 78 | -16711936 |
12 | 86 | -10496 |
14 | 89 | -10496 |
我如何创建一个高效的存储过程或函数来评估每个 [Noise_Id] 的 [Criteria] 列中的表达式,并在 [Criteria] 时转到下一个 [Noise_Id] ] 遇见了吗?
这是我试过的代码:
CREATE TABLE #Results (
Noise_Id int,
Value varchar(MAX))
DECLARE @SQL varchar(MAX)=''
SELECT @SQL =
@SQL+' Insert Into #Results(Noise_Id, Value) Select '+cast(Noise_Id AS varchar(50))+', case when '+Replace([Criteria],'[Value]',Value)+' then [ColorInt] else null end as Value FROM [Noise] where Noise_Id = '+cast(Noise_Id AS varchar(50))
FROM [Noise]
exec (@sql)
select * from #Results
drop table #Results
非常感谢您的帮助!
您需要将 Criteria
分成单独的列:Op
定义应该比较的内容,Criteria
定义要比较的值。
然后您可以分别与每个可能的运算符进行比较。
之后,每个组查询只是一个简单的 TOP 1
。
SELECT
n.Noise_Id
n.[Value],
c.ColorInt
FROM Noise n
CROSS APPLY (
SELECT TOP 1 c.ColorInt
FROM Color c
WHERE
(c.Op = '<' AND n.[Value] < c.Criteria) OR
(c.Op = '<=' AND n.[Value] <= c.Criteria) OR
(c.Op = '=' AND n.[Value] = c.Criteria) OR
(c.Op = '>' AND n.[Value] > c.Criteria) OR
(c.Op = '>=' AND n.[Value] >= c.Criteria)
ORDER BY c.SortOrder
) c
你说你不能修改 Criteria
列。那我们就得自己拆分了。
我假设 Value
总是在开头,比较器在中间,并且有空格。否则会失败。
SELECT
n.Noise_Id
n.[Value],
c.ColorInt
FROM Noise n
CROSS APPLY (
SELECT TOP 1 c.ColorInt
FROM Color c
CROSS APPLY (VALUES (
CAST(RIGHT(c.Criteria, CHARINDEX(' ', REVERSE(c.Criteria)) - 1) AS int) -- same data type as n.Value
) ) v(CriteriaNum)
WHERE
(c.Criteria LIKE '%<%' AND n.[Value] < v.CriteriaNum) OR
(c.Criteria LIKE '%<=%' AND n.[Value] <= v.CriteriaNum) OR
(c.Criteria LIKE '%=%' AND n.[Value] = v.CriteriaNuma) OR
(c.Criteria LIKE '%>%' AND n.[Value] > v.CriteriaNum) OR
(c.Criteria LIKE '%>=%' AND n.[Value] >= v.CriteriaNum)
ORDER BY c.SortOrder
) c