SQL-将函数输出存储为多种用途

时间:2018-11-13 18:05:52

标签: sql sql-server

我在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

3 个答案:

答案 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

这将是一种更多的代码重用方法。