我在Select语句中多次执行函数:
Select Substring(AccNo,5,3),
Case When Substring(AccNo,5,3)='ABC' then
ABC'
Else
'Other'
End as AType
Case When Substring(AccNo,5,3)='DEF' then
'DEF'
Else
'Other'
End as Btype
From MainTable
实际上,我的代码在相同的Function输出上执行了大约20种不同的操作,并且比本示例还要复杂-但是原理仍然存在。
在大多数语言中,我只执行一次功能并将结果存储在变量中,以节省不必要的处理。我在寻找如何在SQL中执行类似操作时遇到麻烦-还是我假设SQL Server非常聪明,并且知道它只需执行一次功能并存储结果?
Set Result=Substring(AccNo,5,3)
Case When Result='ABC'
etc
答案 0 :(得分:3)
我认为您需要
BOM
答案 1 :(得分:1)
我认为在单个查询中不可能做到这一点。我以为apply
可以解决问题:
Select str,
(Case When str = 'ABC' then 'ABC' Else 'Other'
End) as AType,
(Case When str = 'DEF' then 'DEF' Else 'Other'
End) as BType
From MainTable mt cross apply
(values (Substring(AccNo, 5, 3)) v(str);
但事实并非如此。子查询和CTE也不能保证每行仅调用一次该函数。
编辑:
我要回答了,但不能保证。 SQL Server保留重新安排操作的权利,因此即使如此:
select *
from (values (1), (2), (3)) v(x) cross apply
(select newid() as y) y
呼叫newid()
3次。参见here。
答案 2 :(得分:1)
不确定您的预期输出是什么,但是是否需要为每种SUBSTRING(AccNo,5,3)
类型创建一列。可以通过使用PIVOT
这是一个简单的示例:
DECLARE
@t TABLE (AccNo VARCHAR(50), AccName VARCHAR(50))
INSERT INTO @t VALUES
('8001ABC0011047', 'Personal'),
('3022DEF9028683', 'Internal'),
('6709GHI90217096', 'Local'),
('2014JKL17800222', 'International')
SELECT
AccNo
, ABC AType
, DEF BType
, GHI CType
FROM (
SELECT *, SUBSTRING(AccNo,5,3) AccountType
FROM @t
) D
PIVOT(
MAX(AccountType)
FOR AccountType IN(ABC, DEF, GHI, JKL)
) PV
如果在其他查询中经常使用它,则可以使用标量函数,例如:
CREATE FUNCTION GetAccountType
(
@AccNo VARCHAR(50)
)
RETURNS VARCHAR(50)
AS
BEGIN
RETURN
CASE SUBSTRING(@AccNo,5,3)
WHEN 'ABC' THEN 'ABC'
WHEN 'DEF' THEN 'DEF'
ELSE 'Other'
END
END
然后您这样称呼它:
SELECT dbo.GetAccountType(AccNo) AccountType
FROM @t
这将是一种更多的代码重用方法。