SQL - store Function output for multiple uses










0















I'm performing a function multiple times within my Select statement:



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


In reality, my code does about 20 different operations on the same Function output and it is more complicated than this example - but the principle stands.



In most languages, I would just perform the Function ONCE and store the result in a variable, to save unnecessary processing. I'm having trouble finding how I would do something like that in SQL - or do I assume that SQL Server is very smart and knows it only has to perform the function once and store the result?



Set Result=Substring(AccNo,5,3)

Case When Result='ABC'
etc









share|improve this question
























  • I see no where in your example where you are calling a function, unless you are refering to Substring()

    – Ryan Wilson
    Nov 13 '18 at 18:09











  • You mean that you want to get ride from SUBSTRING() function?

    – Sami
    Nov 13 '18 at 18:09











  • Yes - Substring is the function I mean in this example.

    – Lefty
    Nov 13 '18 at 18:10











  • @Sami What do you mean by "get ride from SUBSTRING"?

    – Lefty
    Nov 13 '18 at 18:11















0















I'm performing a function multiple times within my Select statement:



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


In reality, my code does about 20 different operations on the same Function output and it is more complicated than this example - but the principle stands.



In most languages, I would just perform the Function ONCE and store the result in a variable, to save unnecessary processing. I'm having trouble finding how I would do something like that in SQL - or do I assume that SQL Server is very smart and knows it only has to perform the function once and store the result?



Set Result=Substring(AccNo,5,3)

Case When Result='ABC'
etc









share|improve this question
























  • I see no where in your example where you are calling a function, unless you are refering to Substring()

    – Ryan Wilson
    Nov 13 '18 at 18:09











  • You mean that you want to get ride from SUBSTRING() function?

    – Sami
    Nov 13 '18 at 18:09











  • Yes - Substring is the function I mean in this example.

    – Lefty
    Nov 13 '18 at 18:10











  • @Sami What do you mean by "get ride from SUBSTRING"?

    – Lefty
    Nov 13 '18 at 18:11













0












0








0








I'm performing a function multiple times within my Select statement:



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


In reality, my code does about 20 different operations on the same Function output and it is more complicated than this example - but the principle stands.



In most languages, I would just perform the Function ONCE and store the result in a variable, to save unnecessary processing. I'm having trouble finding how I would do something like that in SQL - or do I assume that SQL Server is very smart and knows it only has to perform the function once and store the result?



Set Result=Substring(AccNo,5,3)

Case When Result='ABC'
etc









share|improve this question
















I'm performing a function multiple times within my Select statement:



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


In reality, my code does about 20 different operations on the same Function output and it is more complicated than this example - but the principle stands.



In most languages, I would just perform the Function ONCE and store the result in a variable, to save unnecessary processing. I'm having trouble finding how I would do something like that in SQL - or do I assume that SQL Server is very smart and knows it only has to perform the function once and store the result?



Set Result=Substring(AccNo,5,3)

Case When Result='ABC'
etc






sql sql-server






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 18:13







Lefty

















asked Nov 13 '18 at 18:05









LeftyLefty

34519




34519












  • I see no where in your example where you are calling a function, unless you are refering to Substring()

    – Ryan Wilson
    Nov 13 '18 at 18:09











  • You mean that you want to get ride from SUBSTRING() function?

    – Sami
    Nov 13 '18 at 18:09











  • Yes - Substring is the function I mean in this example.

    – Lefty
    Nov 13 '18 at 18:10











  • @Sami What do you mean by "get ride from SUBSTRING"?

    – Lefty
    Nov 13 '18 at 18:11

















  • I see no where in your example where you are calling a function, unless you are refering to Substring()

    – Ryan Wilson
    Nov 13 '18 at 18:09











  • You mean that you want to get ride from SUBSTRING() function?

    – Sami
    Nov 13 '18 at 18:09











  • Yes - Substring is the function I mean in this example.

    – Lefty
    Nov 13 '18 at 18:10











  • @Sami What do you mean by "get ride from SUBSTRING"?

    – Lefty
    Nov 13 '18 at 18:11
















I see no where in your example where you are calling a function, unless you are refering to Substring()

– Ryan Wilson
Nov 13 '18 at 18:09





I see no where in your example where you are calling a function, unless you are refering to Substring()

– Ryan Wilson
Nov 13 '18 at 18:09













You mean that you want to get ride from SUBSTRING() function?

– Sami
Nov 13 '18 at 18:09





You mean that you want to get ride from SUBSTRING() function?

– Sami
Nov 13 '18 at 18:09













Yes - Substring is the function I mean in this example.

– Lefty
Nov 13 '18 at 18:10





Yes - Substring is the function I mean in this example.

– Lefty
Nov 13 '18 at 18:10













@Sami What do you mean by "get ride from SUBSTRING"?

– Lefty
Nov 13 '18 at 18:11





@Sami What do you mean by "get ride from SUBSTRING"?

– Lefty
Nov 13 '18 at 18:11












3 Answers
3






active

oldest

votes


















3














I think you need



SELECT CASE WHEN Res = 'ABC' THEN 'ABC' ELSE 'Other' END AType,
CASE WHEN Res = 'DEF' THEN 'DEF' ELSE 'Other' END BType
FROM
(
SELECT Substring(AccNo,5,3) Res --You write SUBSTRING() just one time
From MainTable
) T





share|improve this answer























  • This won't work because it doesn't fit with the main structure of the query. Nice idea though, thank you.

    – Lefty
    Nov 13 '18 at 18:15











  • @Lefty Really? How?

    – Sami
    Nov 13 '18 at 18:18






  • 1





    What does "fit the structure" mean? This approach seems to do exactly what you wanted.

    – SMor
    Nov 13 '18 at 18:19











  • @SMor Maybe cause the answer owner is "Sami" thus it won't work

    – Sami
    Nov 13 '18 at 18:21












  • You're right, sorry. My input is a huge JOIN with hundreds of fields - that was the source of my concern - but actually I think it might be irrelevant, I can just use this approach anyway. It will mean quite a bit of change to my existing code but it may well be the answer.

    – Lefty
    Nov 13 '18 at 18:26


















1














I don't think this is possible within a single query. I had thought apply would do the trick:



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);


But it doesn't. Subqueries and CTEs also have no guarantee that the function is called only once per row.



EDIT:



I'm leaving the answer, but there is no guarantee. SQL Server reserves the right to rearrange operations, so even this:



select *
from (values (1), (2), (3)) v(x) cross apply
(select newid() as y) y


Calls newid() three times. See here.






share|improve this answer

























  • This is a workable way of achieving it I think. I will have to do some experimentation. Thank you.

    – Lefty
    Nov 13 '18 at 18:18











  • It's not just workable, it's the standard way of factoring expressions in a query. Whether they call functions or not. Of course, the cross apply expression is processed once per row. that's just how it works.

    – user1443098
    Nov 13 '18 at 18:46


















1














Not sure what is your expected output, but if you need to have a column for each SUBSTRING(AccNo,5,3) type. It's possible by using PIVOT here is a quick example :



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


If you're using it too often in other queries, you can use a scalar function, something like :



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


And then you call it like this :



SELECT dbo.GetAccountType(AccNo) AccountType 
FROM @t


This would be a more code reuse approach.






share|improve this answer























  • I've never come across "Pivot" before so I'm struggling to understand this - but I will persevere and see if it provides a workable solution. In reality, where I've used "Substring" in my example is actually a UDF which is pretty complicated and I've already seen what a speed impact it can have when just running once per Row. If I have to run it 20 times per Row it will likely have a catastrophic effect on the run time. Hence my desire to store its output and re-use it.

    – Lefty
    Nov 13 '18 at 21:24











  • @Lefty, if you are going to reuse the output, I would recommend setting it up, then create a view of it. This way you can reuse it anywhere you want without the need of replicating the whole code.

    – iSR5
    Nov 13 '18 at 22:16











  • A View was the way forward! I just created a view with all the fields in the table, then an extra column with the output of the function. If anything, it seems actually FASTER than reading the table directly and calling the function once! Thank you!

    – Lefty
    Nov 14 '18 at 12:09










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53287046%2fsql-store-function-output-for-multiple-uses%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














I think you need



SELECT CASE WHEN Res = 'ABC' THEN 'ABC' ELSE 'Other' END AType,
CASE WHEN Res = 'DEF' THEN 'DEF' ELSE 'Other' END BType
FROM
(
SELECT Substring(AccNo,5,3) Res --You write SUBSTRING() just one time
From MainTable
) T





share|improve this answer























  • This won't work because it doesn't fit with the main structure of the query. Nice idea though, thank you.

    – Lefty
    Nov 13 '18 at 18:15











  • @Lefty Really? How?

    – Sami
    Nov 13 '18 at 18:18






  • 1





    What does "fit the structure" mean? This approach seems to do exactly what you wanted.

    – SMor
    Nov 13 '18 at 18:19











  • @SMor Maybe cause the answer owner is "Sami" thus it won't work

    – Sami
    Nov 13 '18 at 18:21












  • You're right, sorry. My input is a huge JOIN with hundreds of fields - that was the source of my concern - but actually I think it might be irrelevant, I can just use this approach anyway. It will mean quite a bit of change to my existing code but it may well be the answer.

    – Lefty
    Nov 13 '18 at 18:26















3














I think you need



SELECT CASE WHEN Res = 'ABC' THEN 'ABC' ELSE 'Other' END AType,
CASE WHEN Res = 'DEF' THEN 'DEF' ELSE 'Other' END BType
FROM
(
SELECT Substring(AccNo,5,3) Res --You write SUBSTRING() just one time
From MainTable
) T





share|improve this answer























  • This won't work because it doesn't fit with the main structure of the query. Nice idea though, thank you.

    – Lefty
    Nov 13 '18 at 18:15











  • @Lefty Really? How?

    – Sami
    Nov 13 '18 at 18:18






  • 1





    What does "fit the structure" mean? This approach seems to do exactly what you wanted.

    – SMor
    Nov 13 '18 at 18:19











  • @SMor Maybe cause the answer owner is "Sami" thus it won't work

    – Sami
    Nov 13 '18 at 18:21












  • You're right, sorry. My input is a huge JOIN with hundreds of fields - that was the source of my concern - but actually I think it might be irrelevant, I can just use this approach anyway. It will mean quite a bit of change to my existing code but it may well be the answer.

    – Lefty
    Nov 13 '18 at 18:26













3












3








3







I think you need



SELECT CASE WHEN Res = 'ABC' THEN 'ABC' ELSE 'Other' END AType,
CASE WHEN Res = 'DEF' THEN 'DEF' ELSE 'Other' END BType
FROM
(
SELECT Substring(AccNo,5,3) Res --You write SUBSTRING() just one time
From MainTable
) T





share|improve this answer













I think you need



SELECT CASE WHEN Res = 'ABC' THEN 'ABC' ELSE 'Other' END AType,
CASE WHEN Res = 'DEF' THEN 'DEF' ELSE 'Other' END BType
FROM
(
SELECT Substring(AccNo,5,3) Res --You write SUBSTRING() just one time
From MainTable
) T






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 '18 at 18:11









SamiSami

8,72331241




8,72331241












  • This won't work because it doesn't fit with the main structure of the query. Nice idea though, thank you.

    – Lefty
    Nov 13 '18 at 18:15











  • @Lefty Really? How?

    – Sami
    Nov 13 '18 at 18:18






  • 1





    What does "fit the structure" mean? This approach seems to do exactly what you wanted.

    – SMor
    Nov 13 '18 at 18:19











  • @SMor Maybe cause the answer owner is "Sami" thus it won't work

    – Sami
    Nov 13 '18 at 18:21












  • You're right, sorry. My input is a huge JOIN with hundreds of fields - that was the source of my concern - but actually I think it might be irrelevant, I can just use this approach anyway. It will mean quite a bit of change to my existing code but it may well be the answer.

    – Lefty
    Nov 13 '18 at 18:26

















  • This won't work because it doesn't fit with the main structure of the query. Nice idea though, thank you.

    – Lefty
    Nov 13 '18 at 18:15











  • @Lefty Really? How?

    – Sami
    Nov 13 '18 at 18:18






  • 1





    What does "fit the structure" mean? This approach seems to do exactly what you wanted.

    – SMor
    Nov 13 '18 at 18:19











  • @SMor Maybe cause the answer owner is "Sami" thus it won't work

    – Sami
    Nov 13 '18 at 18:21












  • You're right, sorry. My input is a huge JOIN with hundreds of fields - that was the source of my concern - but actually I think it might be irrelevant, I can just use this approach anyway. It will mean quite a bit of change to my existing code but it may well be the answer.

    – Lefty
    Nov 13 '18 at 18:26
















This won't work because it doesn't fit with the main structure of the query. Nice idea though, thank you.

– Lefty
Nov 13 '18 at 18:15





This won't work because it doesn't fit with the main structure of the query. Nice idea though, thank you.

– Lefty
Nov 13 '18 at 18:15













@Lefty Really? How?

– Sami
Nov 13 '18 at 18:18





@Lefty Really? How?

– Sami
Nov 13 '18 at 18:18




1




1





What does "fit the structure" mean? This approach seems to do exactly what you wanted.

– SMor
Nov 13 '18 at 18:19





What does "fit the structure" mean? This approach seems to do exactly what you wanted.

– SMor
Nov 13 '18 at 18:19













@SMor Maybe cause the answer owner is "Sami" thus it won't work

– Sami
Nov 13 '18 at 18:21






@SMor Maybe cause the answer owner is "Sami" thus it won't work

– Sami
Nov 13 '18 at 18:21














You're right, sorry. My input is a huge JOIN with hundreds of fields - that was the source of my concern - but actually I think it might be irrelevant, I can just use this approach anyway. It will mean quite a bit of change to my existing code but it may well be the answer.

– Lefty
Nov 13 '18 at 18:26





You're right, sorry. My input is a huge JOIN with hundreds of fields - that was the source of my concern - but actually I think it might be irrelevant, I can just use this approach anyway. It will mean quite a bit of change to my existing code but it may well be the answer.

– Lefty
Nov 13 '18 at 18:26













1














I don't think this is possible within a single query. I had thought apply would do the trick:



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);


But it doesn't. Subqueries and CTEs also have no guarantee that the function is called only once per row.



EDIT:



I'm leaving the answer, but there is no guarantee. SQL Server reserves the right to rearrange operations, so even this:



select *
from (values (1), (2), (3)) v(x) cross apply
(select newid() as y) y


Calls newid() three times. See here.






share|improve this answer

























  • This is a workable way of achieving it I think. I will have to do some experimentation. Thank you.

    – Lefty
    Nov 13 '18 at 18:18











  • It's not just workable, it's the standard way of factoring expressions in a query. Whether they call functions or not. Of course, the cross apply expression is processed once per row. that's just how it works.

    – user1443098
    Nov 13 '18 at 18:46















1














I don't think this is possible within a single query. I had thought apply would do the trick:



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);


But it doesn't. Subqueries and CTEs also have no guarantee that the function is called only once per row.



EDIT:



I'm leaving the answer, but there is no guarantee. SQL Server reserves the right to rearrange operations, so even this:



select *
from (values (1), (2), (3)) v(x) cross apply
(select newid() as y) y


Calls newid() three times. See here.






share|improve this answer

























  • This is a workable way of achieving it I think. I will have to do some experimentation. Thank you.

    – Lefty
    Nov 13 '18 at 18:18











  • It's not just workable, it's the standard way of factoring expressions in a query. Whether they call functions or not. Of course, the cross apply expression is processed once per row. that's just how it works.

    – user1443098
    Nov 13 '18 at 18:46













1












1








1







I don't think this is possible within a single query. I had thought apply would do the trick:



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);


But it doesn't. Subqueries and CTEs also have no guarantee that the function is called only once per row.



EDIT:



I'm leaving the answer, but there is no guarantee. SQL Server reserves the right to rearrange operations, so even this:



select *
from (values (1), (2), (3)) v(x) cross apply
(select newid() as y) y


Calls newid() three times. See here.






share|improve this answer















I don't think this is possible within a single query. I had thought apply would do the trick:



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);


But it doesn't. Subqueries and CTEs also have no guarantee that the function is called only once per row.



EDIT:



I'm leaving the answer, but there is no guarantee. SQL Server reserves the right to rearrange operations, so even this:



select *
from (values (1), (2), (3)) v(x) cross apply
(select newid() as y) y


Calls newid() three times. See here.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 13 '18 at 18:33

























answered Nov 13 '18 at 18:10









Gordon LinoffGordon Linoff

767k35300402




767k35300402












  • This is a workable way of achieving it I think. I will have to do some experimentation. Thank you.

    – Lefty
    Nov 13 '18 at 18:18











  • It's not just workable, it's the standard way of factoring expressions in a query. Whether they call functions or not. Of course, the cross apply expression is processed once per row. that's just how it works.

    – user1443098
    Nov 13 '18 at 18:46

















  • This is a workable way of achieving it I think. I will have to do some experimentation. Thank you.

    – Lefty
    Nov 13 '18 at 18:18











  • It's not just workable, it's the standard way of factoring expressions in a query. Whether they call functions or not. Of course, the cross apply expression is processed once per row. that's just how it works.

    – user1443098
    Nov 13 '18 at 18:46
















This is a workable way of achieving it I think. I will have to do some experimentation. Thank you.

– Lefty
Nov 13 '18 at 18:18





This is a workable way of achieving it I think. I will have to do some experimentation. Thank you.

– Lefty
Nov 13 '18 at 18:18













It's not just workable, it's the standard way of factoring expressions in a query. Whether they call functions or not. Of course, the cross apply expression is processed once per row. that's just how it works.

– user1443098
Nov 13 '18 at 18:46





It's not just workable, it's the standard way of factoring expressions in a query. Whether they call functions or not. Of course, the cross apply expression is processed once per row. that's just how it works.

– user1443098
Nov 13 '18 at 18:46











1














Not sure what is your expected output, but if you need to have a column for each SUBSTRING(AccNo,5,3) type. It's possible by using PIVOT here is a quick example :



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


If you're using it too often in other queries, you can use a scalar function, something like :



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


And then you call it like this :



SELECT dbo.GetAccountType(AccNo) AccountType 
FROM @t


This would be a more code reuse approach.






share|improve this answer























  • I've never come across "Pivot" before so I'm struggling to understand this - but I will persevere and see if it provides a workable solution. In reality, where I've used "Substring" in my example is actually a UDF which is pretty complicated and I've already seen what a speed impact it can have when just running once per Row. If I have to run it 20 times per Row it will likely have a catastrophic effect on the run time. Hence my desire to store its output and re-use it.

    – Lefty
    Nov 13 '18 at 21:24











  • @Lefty, if you are going to reuse the output, I would recommend setting it up, then create a view of it. This way you can reuse it anywhere you want without the need of replicating the whole code.

    – iSR5
    Nov 13 '18 at 22:16











  • A View was the way forward! I just created a view with all the fields in the table, then an extra column with the output of the function. If anything, it seems actually FASTER than reading the table directly and calling the function once! Thank you!

    – Lefty
    Nov 14 '18 at 12:09















1














Not sure what is your expected output, but if you need to have a column for each SUBSTRING(AccNo,5,3) type. It's possible by using PIVOT here is a quick example :



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


If you're using it too often in other queries, you can use a scalar function, something like :



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


And then you call it like this :



SELECT dbo.GetAccountType(AccNo) AccountType 
FROM @t


This would be a more code reuse approach.






share|improve this answer























  • I've never come across "Pivot" before so I'm struggling to understand this - but I will persevere and see if it provides a workable solution. In reality, where I've used "Substring" in my example is actually a UDF which is pretty complicated and I've already seen what a speed impact it can have when just running once per Row. If I have to run it 20 times per Row it will likely have a catastrophic effect on the run time. Hence my desire to store its output and re-use it.

    – Lefty
    Nov 13 '18 at 21:24











  • @Lefty, if you are going to reuse the output, I would recommend setting it up, then create a view of it. This way you can reuse it anywhere you want without the need of replicating the whole code.

    – iSR5
    Nov 13 '18 at 22:16











  • A View was the way forward! I just created a view with all the fields in the table, then an extra column with the output of the function. If anything, it seems actually FASTER than reading the table directly and calling the function once! Thank you!

    – Lefty
    Nov 14 '18 at 12:09













1












1








1







Not sure what is your expected output, but if you need to have a column for each SUBSTRING(AccNo,5,3) type. It's possible by using PIVOT here is a quick example :



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


If you're using it too often in other queries, you can use a scalar function, something like :



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


And then you call it like this :



SELECT dbo.GetAccountType(AccNo) AccountType 
FROM @t


This would be a more code reuse approach.






share|improve this answer













Not sure what is your expected output, but if you need to have a column for each SUBSTRING(AccNo,5,3) type. It's possible by using PIVOT here is a quick example :



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


If you're using it too often in other queries, you can use a scalar function, something like :



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


And then you call it like this :



SELECT dbo.GetAccountType(AccNo) AccountType 
FROM @t


This would be a more code reuse approach.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 '18 at 20:01









iSR5iSR5

1,458278




1,458278












  • I've never come across "Pivot" before so I'm struggling to understand this - but I will persevere and see if it provides a workable solution. In reality, where I've used "Substring" in my example is actually a UDF which is pretty complicated and I've already seen what a speed impact it can have when just running once per Row. If I have to run it 20 times per Row it will likely have a catastrophic effect on the run time. Hence my desire to store its output and re-use it.

    – Lefty
    Nov 13 '18 at 21:24











  • @Lefty, if you are going to reuse the output, I would recommend setting it up, then create a view of it. This way you can reuse it anywhere you want without the need of replicating the whole code.

    – iSR5
    Nov 13 '18 at 22:16











  • A View was the way forward! I just created a view with all the fields in the table, then an extra column with the output of the function. If anything, it seems actually FASTER than reading the table directly and calling the function once! Thank you!

    – Lefty
    Nov 14 '18 at 12:09

















  • I've never come across "Pivot" before so I'm struggling to understand this - but I will persevere and see if it provides a workable solution. In reality, where I've used "Substring" in my example is actually a UDF which is pretty complicated and I've already seen what a speed impact it can have when just running once per Row. If I have to run it 20 times per Row it will likely have a catastrophic effect on the run time. Hence my desire to store its output and re-use it.

    – Lefty
    Nov 13 '18 at 21:24











  • @Lefty, if you are going to reuse the output, I would recommend setting it up, then create a view of it. This way you can reuse it anywhere you want without the need of replicating the whole code.

    – iSR5
    Nov 13 '18 at 22:16











  • A View was the way forward! I just created a view with all the fields in the table, then an extra column with the output of the function. If anything, it seems actually FASTER than reading the table directly and calling the function once! Thank you!

    – Lefty
    Nov 14 '18 at 12:09
















I've never come across "Pivot" before so I'm struggling to understand this - but I will persevere and see if it provides a workable solution. In reality, where I've used "Substring" in my example is actually a UDF which is pretty complicated and I've already seen what a speed impact it can have when just running once per Row. If I have to run it 20 times per Row it will likely have a catastrophic effect on the run time. Hence my desire to store its output and re-use it.

– Lefty
Nov 13 '18 at 21:24





I've never come across "Pivot" before so I'm struggling to understand this - but I will persevere and see if it provides a workable solution. In reality, where I've used "Substring" in my example is actually a UDF which is pretty complicated and I've already seen what a speed impact it can have when just running once per Row. If I have to run it 20 times per Row it will likely have a catastrophic effect on the run time. Hence my desire to store its output and re-use it.

– Lefty
Nov 13 '18 at 21:24













@Lefty, if you are going to reuse the output, I would recommend setting it up, then create a view of it. This way you can reuse it anywhere you want without the need of replicating the whole code.

– iSR5
Nov 13 '18 at 22:16





@Lefty, if you are going to reuse the output, I would recommend setting it up, then create a view of it. This way you can reuse it anywhere you want without the need of replicating the whole code.

– iSR5
Nov 13 '18 at 22:16













A View was the way forward! I just created a view with all the fields in the table, then an extra column with the output of the function. If anything, it seems actually FASTER than reading the table directly and calling the function once! Thank you!

– Lefty
Nov 14 '18 at 12:09





A View was the way forward! I just created a view with all the fields in the table, then an extra column with the output of the function. If anything, it seems actually FASTER than reading the table directly and calling the function once! Thank you!

– Lefty
Nov 14 '18 at 12:09

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53287046%2fsql-store-function-output-for-multiple-uses%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

How to read a connectionString WITH PROVIDER in .NET Core?

In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

Museum of Modern and Contemporary Art of Trento and Rovereto