ask*_*low 11 sql t-sql sql-server sql-server-2012
我想根据我的列值进行算术运算.请考虑以下示例
CREATE TABLE #test
(
cont_sal INT,
check_value INT,
operator VARCHAR(50)
)
INSERT #test
VALUES (10,20,'+'),
(20,10,'+'),
(10,20,'-'),
(20,10,'-')
Run Code Online (Sandbox Code Playgroud)
预期结果:
cont_sal check_value result
-------- ----------- ------
10 20 30
20 10 30
10 20 -10
20 10 10
Run Code Online (Sandbox Code Playgroud)
我可以使用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
Run Code Online (Sandbox Code Playgroud)
但有没有办法动态地做到这一点.操作员可以像任何东西/,%,*.像这样的东西
DECLARE @sql NVARCHAR(max)=''
SET @sql = 'select cont_sal ' + 'operator'
+ ' check_value from #test '
--PRINT @sql
EXEC Sp_executesql
@sql
Run Code Online (Sandbox Code Playgroud)
这显然不起作用
消息102,级别15,状态1,行1'check_value'附近的语法不正确.
好问题.
我会使用case表达式,因为:
但也有其他选择.您可以构建然后执行动态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);
Run Code Online (Sandbox Code Playgroud)
或者您可以使用交叉应用来使用强力计算结果.
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
;
Run Code Online (Sandbox Code Playgroud)
这里计算每个可能的操作.那些不需要的东西会从结果集中过滤掉.这种方法更易于读写,但运行从不需要的计算.也就是说,它确实生成了一个更快的查询计划,这是我的动态示例.
编辑
感谢@Damien_The_Unbeliever,他指出我的漏洞除以零错误.我已经使用NULLIF将0替换为空值,这避免了错误.
我只更新了第二个例子.