我想根据我的列值进行算术运算。考虑以下示例
CREATE TABLE #test
(
cont_sal INT,
check_value INT,
operator VARCHAR(50)
)
INSERT #test
VALUES (10,20,'+'),
(20,10,'+'),
(10,20,'-'),
(20,10,'-')
预期结果:
cont_sal check_value result
-------- ----------- ------
10 20 30
20 10 30
10 20 -10
20 10 10
我可以使用CASE
语句来做到这一点。
SELECT cont_sal,
check_value,
CASE
WHEN operator = '+' THEN cont_sal + check_value
when operator = '-' THEN cont_sal - check_value
END result
FROM #test
但是有没有办法动态地做到这一点。运算符可以是 /
、%
、*
等任何内容。像这样的事情
DECLARE @sql NVARCHAR(max)=''
SET @sql = 'select cont_sal ' + 'operator'
+ ' check_value from #test '
--PRINT @sql
EXEC Sp_executesql
@sql
这显然不起作用
Msg 102, Level 15, State 1, Line 1 Incorrect syntax near 'check_value'.
最佳答案
很好的问题。
我会使用 case 表达式,因为:
- 只有five arithmetic operators .
- 您无法直接参数化算术运算符。
- 您无法内联执行动态 SQL。
但是还有其他选择。您可以构建然后执行动态 SQL 语句。
-- Query will be stored here.
DECLARE @Qry VARCHAR(255) = '';
-- Build up the query.
SELECT
@Qry =
@Qry
+ CASE ROW_NUMBER() OVER (ORDER BY cont_sal)
WHEN 1 THEN 'SELECT '
ELSE 'UNION ALL SELECT '
END
+ ''''
+ Expression
+ ''''
+ ' AS Expression,'
+ Expression
+ ' AS Result '
FROM
#test AS t
CROSS APPLY
(
-- Avoid typing expression twice.
SELECT
CAST(cont_sal AS VARCHAR(50))
+ ' '
+ operator
+ ' '
+ CAST(check_value AS VARCHAR(50)) AS Expression
) AS ex
;
-- Execute it.
EXECUTE(@Qry);
或者您可以使用交叉应用来暴力计算结果。
SELECT
*
FROM
#test AS t
CROSS APPLY
(
VALUES
('+', cont_sal + check_value),
('-', cont_sal - check_value),
('*', cont_sal * check_value),
('/', cont_sal / NULLIF(check_value, 0)),
('%', cont_sal % NULLIF(check_value, 0))
) AS ex(operator, result)
WHERE
ex.operator = t.operator
;
这里计算每一个可能的操作。那些不需要的将从结果集中过滤掉。这种方法更容易阅读和编写,但运行不需要的计算。也就是说,它确实生成了比我的动态示例更快的查询计划。
编辑
感谢@Damien_The_Unknowner,他指出了我除以零错误的漏洞。我用过NULLIF将 0 替换为 null,从而避免错误。
我只更新了第二个示例。
关于sql - 基于列值的算术/逻辑运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35334076/