SQL - store Function output for multiple uses
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
add a comment |
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
I see no where in your example where you are calling a function, unless you are refering toSubstring()
– Ryan Wilson
Nov 13 '18 at 18:09
You mean that you want to get ride fromSUBSTRING()
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
add a comment |
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
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
sql sql-server
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 toSubstring()
– Ryan Wilson
Nov 13 '18 at 18:09
You mean that you want to get ride fromSUBSTRING()
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
add a comment |
I see no where in your example where you are calling a function, unless you are refering toSubstring()
– Ryan Wilson
Nov 13 '18 at 18:09
You mean that you want to get ride fromSUBSTRING()
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
add a comment |
3 Answers
3
active
oldest
votes
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
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
|
show 3 more comments
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.
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
add a comment |
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.
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
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
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
|
show 3 more comments
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
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
|
show 3 more comments
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
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
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
|
show 3 more comments
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
|
show 3 more comments
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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