我有一组具有以下结构重复多次的表:
Sign|Value
|1000
-|1000
所以有一个“符号”列,后面是“值”列...并且两个值都是 varchar(..)
。我正在根据此基础数据构建表格,并希望使用符号将其转换为小数。
目前我一直在做以下事情:
CASE
WHEN LTRIM(RTRIM(s.PreviousPointBalanceSign)) = '-'
THEN -1 * CAST(s.PreviousPointBalance AS decimal(14,2))
ELSE CAST(s.PreviousPointBalance AS decimal(14,2))
END AS PreviousPointBalance
但我想知道使用函数来实现这一点是否会给我带来更好的性能?
最佳答案
您打算使用哪种功能?基本上功能对性能没有帮助。它们简化了代码,使您能够重用代码等等。普通 SQL 总是更好或相同。在您的情况下,最好的解决方案是以正确的方式存储数据,但是如果不可能,则尝试以不同的方式做同样的事情。例如:
1) CASE WHEN Sign like '%-%';
2) CASE WHEN LEN(Sign) > 0.
3) You can also avoid CASE at all: SELECT CAST(Value AS Decimal(14,2)) * ((-1 + (LEN(Sign)^1) * 2))
您还可以使用计算持久化列来计算插入时的值。
更新:
经过小型测试后,优化器对所有方式显示了完全相同的计划:
CREATE TABLE #test
(
value VARCHAR(3),
[sign] VARCHAR(3)
);
DECLARE @a INT = 0;
WHILE (@a < 1000)
BEGIN
INSERT INTO #test VALUES (CAST(@a AS VARCHAR(100)), CASE WHEN @a%2 =0 THEN '-' ELSE '' END )
SET @a=@a+1;
END
SELECT
CASE
WHEN LTRIM(RTRIM(s.[sign])) = '-'
THEN -1 * CAST(s.value AS decimal(14,2))
ELSE CAST(s.value AS decimal(14,2))
END AS PreviousPointBalance
FROM #test s
SELECT
CASE
WHEN s.[sign] LIKE '%-%'
THEN -1 * CAST(s.value AS decimal(14,2))
ELSE CAST(s.value AS decimal(14,2))
END AS PreviousPointBalance
FROM #test s
SELECT
CASE
WHEN LEN(s.sign) >0
THEN -1 * CAST(s.value AS decimal(14,2))
ELSE CAST(s.value AS decimal(14,2))
END AS PreviousPointBalance
FROM #test s
SELECT CAST(Value AS Decimal(14,2)) * ((-1 + (LEN(Sign)^1) * 2)) AS PreviousPointBalance
FROM #test s
关于sql-server - T-SQL 中的 CASE 语句或函数具有更好的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29626797/