评估几个表达式,当为真时继续下一个 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