Does SQL Server support GREATEST and LEAST, if not what is the common workaround?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
Reviewing this question it seems like that's a lot of work that shouldn't be needed. They're trying to extend a range with a date. In other databases, you would just use greatest and least..
least(extendDate,min), greatest(extendDate,max)
When I try to use these though, I get
'least' is not a recognized built-in function name.
'greatest' is not a recognized built-in function name.
That would cover extension in either direction.
For the purposes of the question, you would still have to do exclusive range replacement.
I'm just wondering how SQL Server users implement query patterns to mimic least and greatest functionality.
- PostgreSQL
GREATEST/LEAST
- MySQL
GREATEST/LEAST
- MariaDB
GREATESTLEAST
- DB2
GREATESTLEAST
- Oracle
GREATESTLEAST
Do you unroll the conditions into CASE statements or is there an extension, third party add-on, or license from Microsoft that enables this functionality?
sql-server t-sql feature-comparison
add a comment |
Reviewing this question it seems like that's a lot of work that shouldn't be needed. They're trying to extend a range with a date. In other databases, you would just use greatest and least..
least(extendDate,min), greatest(extendDate,max)
When I try to use these though, I get
'least' is not a recognized built-in function name.
'greatest' is not a recognized built-in function name.
That would cover extension in either direction.
For the purposes of the question, you would still have to do exclusive range replacement.
I'm just wondering how SQL Server users implement query patterns to mimic least and greatest functionality.
- PostgreSQL
GREATEST/LEAST
- MySQL
GREATEST/LEAST
- MariaDB
GREATESTLEAST
- DB2
GREATESTLEAST
- Oracle
GREATESTLEAST
Do you unroll the conditions into CASE statements or is there an extension, third party add-on, or license from Microsoft that enables this functionality?
sql-server t-sql feature-comparison
add a comment |
Reviewing this question it seems like that's a lot of work that shouldn't be needed. They're trying to extend a range with a date. In other databases, you would just use greatest and least..
least(extendDate,min), greatest(extendDate,max)
When I try to use these though, I get
'least' is not a recognized built-in function name.
'greatest' is not a recognized built-in function name.
That would cover extension in either direction.
For the purposes of the question, you would still have to do exclusive range replacement.
I'm just wondering how SQL Server users implement query patterns to mimic least and greatest functionality.
- PostgreSQL
GREATEST/LEAST
- MySQL
GREATEST/LEAST
- MariaDB
GREATESTLEAST
- DB2
GREATESTLEAST
- Oracle
GREATESTLEAST
Do you unroll the conditions into CASE statements or is there an extension, third party add-on, or license from Microsoft that enables this functionality?
sql-server t-sql feature-comparison
Reviewing this question it seems like that's a lot of work that shouldn't be needed. They're trying to extend a range with a date. In other databases, you would just use greatest and least..
least(extendDate,min), greatest(extendDate,max)
When I try to use these though, I get
'least' is not a recognized built-in function name.
'greatest' is not a recognized built-in function name.
That would cover extension in either direction.
For the purposes of the question, you would still have to do exclusive range replacement.
I'm just wondering how SQL Server users implement query patterns to mimic least and greatest functionality.
- PostgreSQL
GREATEST/LEAST
- MySQL
GREATEST/LEAST
- MariaDB
GREATESTLEAST
- DB2
GREATESTLEAST
- Oracle
GREATESTLEAST
Do you unroll the conditions into CASE statements or is there an extension, third party add-on, or license from Microsoft that enables this functionality?
sql-server t-sql feature-comparison
sql-server t-sql feature-comparison
edited Nov 1 '18 at 6:18
Pang
1316
1316
asked Sep 27 '17 at 18:57
Evan CarrollEvan Carroll
33.9k1080236
33.9k1080236
add a comment |
add a comment |
6 Answers
6
active
oldest
votes
One common method is to use the VALUES clause, and CROSS APPLY the two columns aliased as a single column, then get the MIN and MAX of each.
SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM dbo.Users AS u
CROSS APPLY ( VALUES ( u.CreationDate ), ( u.LastAccessDate )) AS x ( CombinedDate );
There are other ways of writing it, for example using UNION ALL
SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM dbo.Users AS u
CROSS APPLY ( SELECT u.CreationDate UNION ALL SELECT u.LastAccessDate ) AS x(CombinedDate);
However, the resulting query plans seem to be the same.
add a comment |
You can also put the values inline in a subquery. Like this:
select (select max(i) from (values (1), (2), (5), (1), (6)) AS T(i)) greatest,
(select min(i) from (values (1), (2), (5), (1), (6)) AS T(i)) least
add a comment |
This would be a good start -
CASE WHEN A > B THEN A ELSE B END
It's a good suggestion but it was mentioned in the question with "unrolling the condition into CASE statements"
– Evan Carroll
Aug 17 '18 at 1:25
add a comment |
LEAST equivalent:
IIF(@a < @b, @a, @b)
GREATEST equivalent:
IIF(@a > @b, @a, @b)
1
How do you do that for three or more values, e.g.least(5,6,7,8,9)?
– a_horse_with_no_name
Sep 20 '18 at 10:42
@a_horse_with_no_name Use nested IIF's
– Elnur
Sep 20 '18 at 13:53
add a comment |
I create user-defined functions, e.g.
create function dbo.udf_LeastInt(@a int, @b int)
returns int
with schemabinding
as
begin
return case when @a <= @b then @a
when @b < @a then @b
else null
end
end
Although it may work in simple cases, there are several issues with this approach however:
- Annoyingly you have to make separate functions for each data type.
- It handles only 2 parameters, so one may need more functions to handle many parameters or use nested calls of the same functions.
- It would be better (more efficient) as an inline TVF rather than a scalar function. That has to do with the implementation of scalar functions at heart. There are many blogs about it, see for example SQL 101: Parallelism Inhibitors – Scalar User Defined Functions (by John Kehayias.
- If one of the arguments is null, it returns null. This matches what the
leastoperator does in Oracle and MySQL, but differs from Postgres. But this armouring against null makes it more verbose (if you know they won't be null, a plaincase when @a <= @b then @a else @b endwould work).
All in all it may be better to write out the case statement longhand if performance matters. I've even resorted to generating nested case statements on the client side when there are several values to compare.
add a comment |
I was intending to add comment to @ed-avis answer, but unable to do so, due to lack of reputation, so posting this as extension to his answer.
I've eliminated disadvantage of "Annoyingly you have to make separate functions for each data type." Using SQL_VARIANT.
Here is my implementation:
CREATE OR ALTER FUNCTION my_least(@a SQL_VARIANT, @b SQL_VARIANT)
returns SQL_VARIANT
with schemabinding
as
begin
return case when @a <= @b then @a
when @b < @a then @b
WHEN @a IS NULL THEN @b
WHEN @b IS NULL THEN @a
else null
end
END;
Also this function handles NULLs like postgresql version.
This function could be added to DB for convenience, but it's 10 times slower, than using built in IIF. My tests shows, that such function with exact type (datetime) performs same as sql_variant version.
P.S.
I run some tests on data-set of 350k values, and seems that performance is the same, sql_variant is tiny bit faster, but I believe it's just jitters.
But any way IIF version is 10x times faster!!!
I haven't tested inline CASE WHEN but basically for t-sql IIF is same as case, and iif get's converted by optimizer to case expression.
The fact that IIF is translated into CASE also has an impact on other
aspects of the behavior of this function.
CONCLUSION: It's faster to use IIF if performance matters, but for prototyping, or if code clarity is more needed, and no big calculations are involved, provided function can be used.
1
You say that "sqlvariant is tiny bit faster" and that "IIF version is 10x times faster". faster than what?
– ypercubeᵀᴹ
Jan 2 at 2:18
Sql variant ver is around same speed as concreete version, like provided by another answer. In my test it was 80ms fater (out from 15sec), I assumme that just statistics error. And usingiif(a<b, a, b)is 10 times faster as any user defined function.
– Bogdan Mart
Jan 2 at 2:21
To be clear, I used my code with sql_variant replaced with datetime, as second function. After tests it seems that sql_variant don't add any overhead, but user defined functions are way slower, than built-in
– Bogdan Mart
Jan 2 at 2:22
But is any of these functions - includingIIF()- faster than using aCASEexpression? My point is, that since you went into the trouble of performance testing, you should test all the suggested methods/answers.
– ypercubeᵀᴹ
Jan 2 at 2:26
1
@yper-crazyhat-cubeᵀᴹ updated answer. Won't edit it more, just wanted to add comment regarding sql_variant to ed-avis's answer, but due to lack of pints had to write expanded answer :-)
– Bogdan Mart
Jan 3 at 0:42
|
show 3 more comments
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
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: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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%2fdba.stackexchange.com%2fquestions%2f187090%2fdoes-sql-server-support-greatest-and-least-if-not-what-is-the-common-workaround%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
One common method is to use the VALUES clause, and CROSS APPLY the two columns aliased as a single column, then get the MIN and MAX of each.
SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM dbo.Users AS u
CROSS APPLY ( VALUES ( u.CreationDate ), ( u.LastAccessDate )) AS x ( CombinedDate );
There are other ways of writing it, for example using UNION ALL
SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM dbo.Users AS u
CROSS APPLY ( SELECT u.CreationDate UNION ALL SELECT u.LastAccessDate ) AS x(CombinedDate);
However, the resulting query plans seem to be the same.
add a comment |
One common method is to use the VALUES clause, and CROSS APPLY the two columns aliased as a single column, then get the MIN and MAX of each.
SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM dbo.Users AS u
CROSS APPLY ( VALUES ( u.CreationDate ), ( u.LastAccessDate )) AS x ( CombinedDate );
There are other ways of writing it, for example using UNION ALL
SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM dbo.Users AS u
CROSS APPLY ( SELECT u.CreationDate UNION ALL SELECT u.LastAccessDate ) AS x(CombinedDate);
However, the resulting query plans seem to be the same.
add a comment |
One common method is to use the VALUES clause, and CROSS APPLY the two columns aliased as a single column, then get the MIN and MAX of each.
SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM dbo.Users AS u
CROSS APPLY ( VALUES ( u.CreationDate ), ( u.LastAccessDate )) AS x ( CombinedDate );
There are other ways of writing it, for example using UNION ALL
SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM dbo.Users AS u
CROSS APPLY ( SELECT u.CreationDate UNION ALL SELECT u.LastAccessDate ) AS x(CombinedDate);
However, the resulting query plans seem to be the same.
One common method is to use the VALUES clause, and CROSS APPLY the two columns aliased as a single column, then get the MIN and MAX of each.
SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM dbo.Users AS u
CROSS APPLY ( VALUES ( u.CreationDate ), ( u.LastAccessDate )) AS x ( CombinedDate );
There are other ways of writing it, for example using UNION ALL
SELECT MIN(x.CombinedDate) AS least, MAX(x.CombinedDate) AS greatest
FROM dbo.Users AS u
CROSS APPLY ( SELECT u.CreationDate UNION ALL SELECT u.LastAccessDate ) AS x(CombinedDate);
However, the resulting query plans seem to be the same.
edited Jul 23 '18 at 23:12
Evan Carroll
33.9k1080236
33.9k1080236
answered Sep 27 '17 at 20:33
Erik DarlingErik Darling
23.1k1370114
23.1k1370114
add a comment |
add a comment |
You can also put the values inline in a subquery. Like this:
select (select max(i) from (values (1), (2), (5), (1), (6)) AS T(i)) greatest,
(select min(i) from (values (1), (2), (5), (1), (6)) AS T(i)) least
add a comment |
You can also put the values inline in a subquery. Like this:
select (select max(i) from (values (1), (2), (5), (1), (6)) AS T(i)) greatest,
(select min(i) from (values (1), (2), (5), (1), (6)) AS T(i)) least
add a comment |
You can also put the values inline in a subquery. Like this:
select (select max(i) from (values (1), (2), (5), (1), (6)) AS T(i)) greatest,
(select min(i) from (values (1), (2), (5), (1), (6)) AS T(i)) least
You can also put the values inline in a subquery. Like this:
select (select max(i) from (values (1), (2), (5), (1), (6)) AS T(i)) greatest,
(select min(i) from (values (1), (2), (5), (1), (6)) AS T(i)) least
answered Sep 27 '17 at 22:10
David Browne - MicrosoftDavid Browne - Microsoft
12.7k732
12.7k732
add a comment |
add a comment |
This would be a good start -
CASE WHEN A > B THEN A ELSE B END
It's a good suggestion but it was mentioned in the question with "unrolling the condition into CASE statements"
– Evan Carroll
Aug 17 '18 at 1:25
add a comment |
This would be a good start -
CASE WHEN A > B THEN A ELSE B END
It's a good suggestion but it was mentioned in the question with "unrolling the condition into CASE statements"
– Evan Carroll
Aug 17 '18 at 1:25
add a comment |
This would be a good start -
CASE WHEN A > B THEN A ELSE B END
This would be a good start -
CASE WHEN A > B THEN A ELSE B END
answered Aug 16 '18 at 23:10
Jim GettmaJim Gettma
311
311
It's a good suggestion but it was mentioned in the question with "unrolling the condition into CASE statements"
– Evan Carroll
Aug 17 '18 at 1:25
add a comment |
It's a good suggestion but it was mentioned in the question with "unrolling the condition into CASE statements"
– Evan Carroll
Aug 17 '18 at 1:25
It's a good suggestion but it was mentioned in the question with "unrolling the condition into CASE statements"
– Evan Carroll
Aug 17 '18 at 1:25
It's a good suggestion but it was mentioned in the question with "unrolling the condition into CASE statements"
– Evan Carroll
Aug 17 '18 at 1:25
add a comment |
LEAST equivalent:
IIF(@a < @b, @a, @b)
GREATEST equivalent:
IIF(@a > @b, @a, @b)
1
How do you do that for three or more values, e.g.least(5,6,7,8,9)?
– a_horse_with_no_name
Sep 20 '18 at 10:42
@a_horse_with_no_name Use nested IIF's
– Elnur
Sep 20 '18 at 13:53
add a comment |
LEAST equivalent:
IIF(@a < @b, @a, @b)
GREATEST equivalent:
IIF(@a > @b, @a, @b)
1
How do you do that for three or more values, e.g.least(5,6,7,8,9)?
– a_horse_with_no_name
Sep 20 '18 at 10:42
@a_horse_with_no_name Use nested IIF's
– Elnur
Sep 20 '18 at 13:53
add a comment |
LEAST equivalent:
IIF(@a < @b, @a, @b)
GREATEST equivalent:
IIF(@a > @b, @a, @b)
LEAST equivalent:
IIF(@a < @b, @a, @b)
GREATEST equivalent:
IIF(@a > @b, @a, @b)
answered Sep 20 '18 at 10:39
ElnurElnur
211
211
1
How do you do that for three or more values, e.g.least(5,6,7,8,9)?
– a_horse_with_no_name
Sep 20 '18 at 10:42
@a_horse_with_no_name Use nested IIF's
– Elnur
Sep 20 '18 at 13:53
add a comment |
1
How do you do that for three or more values, e.g.least(5,6,7,8,9)?
– a_horse_with_no_name
Sep 20 '18 at 10:42
@a_horse_with_no_name Use nested IIF's
– Elnur
Sep 20 '18 at 13:53
1
1
How do you do that for three or more values, e.g.
least(5,6,7,8,9)?– a_horse_with_no_name
Sep 20 '18 at 10:42
How do you do that for three or more values, e.g.
least(5,6,7,8,9)?– a_horse_with_no_name
Sep 20 '18 at 10:42
@a_horse_with_no_name Use nested IIF's
– Elnur
Sep 20 '18 at 13:53
@a_horse_with_no_name Use nested IIF's
– Elnur
Sep 20 '18 at 13:53
add a comment |
I create user-defined functions, e.g.
create function dbo.udf_LeastInt(@a int, @b int)
returns int
with schemabinding
as
begin
return case when @a <= @b then @a
when @b < @a then @b
else null
end
end
Although it may work in simple cases, there are several issues with this approach however:
- Annoyingly you have to make separate functions for each data type.
- It handles only 2 parameters, so one may need more functions to handle many parameters or use nested calls of the same functions.
- It would be better (more efficient) as an inline TVF rather than a scalar function. That has to do with the implementation of scalar functions at heart. There are many blogs about it, see for example SQL 101: Parallelism Inhibitors – Scalar User Defined Functions (by John Kehayias.
- If one of the arguments is null, it returns null. This matches what the
leastoperator does in Oracle and MySQL, but differs from Postgres. But this armouring against null makes it more verbose (if you know they won't be null, a plaincase when @a <= @b then @a else @b endwould work).
All in all it may be better to write out the case statement longhand if performance matters. I've even resorted to generating nested case statements on the client side when there are several values to compare.
add a comment |
I create user-defined functions, e.g.
create function dbo.udf_LeastInt(@a int, @b int)
returns int
with schemabinding
as
begin
return case when @a <= @b then @a
when @b < @a then @b
else null
end
end
Although it may work in simple cases, there are several issues with this approach however:
- Annoyingly you have to make separate functions for each data type.
- It handles only 2 parameters, so one may need more functions to handle many parameters or use nested calls of the same functions.
- It would be better (more efficient) as an inline TVF rather than a scalar function. That has to do with the implementation of scalar functions at heart. There are many blogs about it, see for example SQL 101: Parallelism Inhibitors – Scalar User Defined Functions (by John Kehayias.
- If one of the arguments is null, it returns null. This matches what the
leastoperator does in Oracle and MySQL, but differs from Postgres. But this armouring against null makes it more verbose (if you know they won't be null, a plaincase when @a <= @b then @a else @b endwould work).
All in all it may be better to write out the case statement longhand if performance matters. I've even resorted to generating nested case statements on the client side when there are several values to compare.
add a comment |
I create user-defined functions, e.g.
create function dbo.udf_LeastInt(@a int, @b int)
returns int
with schemabinding
as
begin
return case when @a <= @b then @a
when @b < @a then @b
else null
end
end
Although it may work in simple cases, there are several issues with this approach however:
- Annoyingly you have to make separate functions for each data type.
- It handles only 2 parameters, so one may need more functions to handle many parameters or use nested calls of the same functions.
- It would be better (more efficient) as an inline TVF rather than a scalar function. That has to do with the implementation of scalar functions at heart. There are many blogs about it, see for example SQL 101: Parallelism Inhibitors – Scalar User Defined Functions (by John Kehayias.
- If one of the arguments is null, it returns null. This matches what the
leastoperator does in Oracle and MySQL, but differs from Postgres. But this armouring against null makes it more verbose (if you know they won't be null, a plaincase when @a <= @b then @a else @b endwould work).
All in all it may be better to write out the case statement longhand if performance matters. I've even resorted to generating nested case statements on the client side when there are several values to compare.
I create user-defined functions, e.g.
create function dbo.udf_LeastInt(@a int, @b int)
returns int
with schemabinding
as
begin
return case when @a <= @b then @a
when @b < @a then @b
else null
end
end
Although it may work in simple cases, there are several issues with this approach however:
- Annoyingly you have to make separate functions for each data type.
- It handles only 2 parameters, so one may need more functions to handle many parameters or use nested calls of the same functions.
- It would be better (more efficient) as an inline TVF rather than a scalar function. That has to do with the implementation of scalar functions at heart. There are many blogs about it, see for example SQL 101: Parallelism Inhibitors – Scalar User Defined Functions (by John Kehayias.
- If one of the arguments is null, it returns null. This matches what the
leastoperator does in Oracle and MySQL, but differs from Postgres. But this armouring against null makes it more verbose (if you know they won't be null, a plaincase when @a <= @b then @a else @b endwould work).
All in all it may be better to write out the case statement longhand if performance matters. I've even resorted to generating nested case statements on the client side when there are several values to compare.
edited Mar 27 '18 at 8:58
answered Mar 6 '18 at 10:35
Ed AvisEd Avis
1193
1193
add a comment |
add a comment |
I was intending to add comment to @ed-avis answer, but unable to do so, due to lack of reputation, so posting this as extension to his answer.
I've eliminated disadvantage of "Annoyingly you have to make separate functions for each data type." Using SQL_VARIANT.
Here is my implementation:
CREATE OR ALTER FUNCTION my_least(@a SQL_VARIANT, @b SQL_VARIANT)
returns SQL_VARIANT
with schemabinding
as
begin
return case when @a <= @b then @a
when @b < @a then @b
WHEN @a IS NULL THEN @b
WHEN @b IS NULL THEN @a
else null
end
END;
Also this function handles NULLs like postgresql version.
This function could be added to DB for convenience, but it's 10 times slower, than using built in IIF. My tests shows, that such function with exact type (datetime) performs same as sql_variant version.
P.S.
I run some tests on data-set of 350k values, and seems that performance is the same, sql_variant is tiny bit faster, but I believe it's just jitters.
But any way IIF version is 10x times faster!!!
I haven't tested inline CASE WHEN but basically for t-sql IIF is same as case, and iif get's converted by optimizer to case expression.
The fact that IIF is translated into CASE also has an impact on other
aspects of the behavior of this function.
CONCLUSION: It's faster to use IIF if performance matters, but for prototyping, or if code clarity is more needed, and no big calculations are involved, provided function can be used.
1
You say that "sqlvariant is tiny bit faster" and that "IIF version is 10x times faster". faster than what?
– ypercubeᵀᴹ
Jan 2 at 2:18
Sql variant ver is around same speed as concreete version, like provided by another answer. In my test it was 80ms fater (out from 15sec), I assumme that just statistics error. And usingiif(a<b, a, b)is 10 times faster as any user defined function.
– Bogdan Mart
Jan 2 at 2:21
To be clear, I used my code with sql_variant replaced with datetime, as second function. After tests it seems that sql_variant don't add any overhead, but user defined functions are way slower, than built-in
– Bogdan Mart
Jan 2 at 2:22
But is any of these functions - includingIIF()- faster than using aCASEexpression? My point is, that since you went into the trouble of performance testing, you should test all the suggested methods/answers.
– ypercubeᵀᴹ
Jan 2 at 2:26
1
@yper-crazyhat-cubeᵀᴹ updated answer. Won't edit it more, just wanted to add comment regarding sql_variant to ed-avis's answer, but due to lack of pints had to write expanded answer :-)
– Bogdan Mart
Jan 3 at 0:42
|
show 3 more comments
I was intending to add comment to @ed-avis answer, but unable to do so, due to lack of reputation, so posting this as extension to his answer.
I've eliminated disadvantage of "Annoyingly you have to make separate functions for each data type." Using SQL_VARIANT.
Here is my implementation:
CREATE OR ALTER FUNCTION my_least(@a SQL_VARIANT, @b SQL_VARIANT)
returns SQL_VARIANT
with schemabinding
as
begin
return case when @a <= @b then @a
when @b < @a then @b
WHEN @a IS NULL THEN @b
WHEN @b IS NULL THEN @a
else null
end
END;
Also this function handles NULLs like postgresql version.
This function could be added to DB for convenience, but it's 10 times slower, than using built in IIF. My tests shows, that such function with exact type (datetime) performs same as sql_variant version.
P.S.
I run some tests on data-set of 350k values, and seems that performance is the same, sql_variant is tiny bit faster, but I believe it's just jitters.
But any way IIF version is 10x times faster!!!
I haven't tested inline CASE WHEN but basically for t-sql IIF is same as case, and iif get's converted by optimizer to case expression.
The fact that IIF is translated into CASE also has an impact on other
aspects of the behavior of this function.
CONCLUSION: It's faster to use IIF if performance matters, but for prototyping, or if code clarity is more needed, and no big calculations are involved, provided function can be used.
1
You say that "sqlvariant is tiny bit faster" and that "IIF version is 10x times faster". faster than what?
– ypercubeᵀᴹ
Jan 2 at 2:18
Sql variant ver is around same speed as concreete version, like provided by another answer. In my test it was 80ms fater (out from 15sec), I assumme that just statistics error. And usingiif(a<b, a, b)is 10 times faster as any user defined function.
– Bogdan Mart
Jan 2 at 2:21
To be clear, I used my code with sql_variant replaced with datetime, as second function. After tests it seems that sql_variant don't add any overhead, but user defined functions are way slower, than built-in
– Bogdan Mart
Jan 2 at 2:22
But is any of these functions - includingIIF()- faster than using aCASEexpression? My point is, that since you went into the trouble of performance testing, you should test all the suggested methods/answers.
– ypercubeᵀᴹ
Jan 2 at 2:26
1
@yper-crazyhat-cubeᵀᴹ updated answer. Won't edit it more, just wanted to add comment regarding sql_variant to ed-avis's answer, but due to lack of pints had to write expanded answer :-)
– Bogdan Mart
Jan 3 at 0:42
|
show 3 more comments
I was intending to add comment to @ed-avis answer, but unable to do so, due to lack of reputation, so posting this as extension to his answer.
I've eliminated disadvantage of "Annoyingly you have to make separate functions for each data type." Using SQL_VARIANT.
Here is my implementation:
CREATE OR ALTER FUNCTION my_least(@a SQL_VARIANT, @b SQL_VARIANT)
returns SQL_VARIANT
with schemabinding
as
begin
return case when @a <= @b then @a
when @b < @a then @b
WHEN @a IS NULL THEN @b
WHEN @b IS NULL THEN @a
else null
end
END;
Also this function handles NULLs like postgresql version.
This function could be added to DB for convenience, but it's 10 times slower, than using built in IIF. My tests shows, that such function with exact type (datetime) performs same as sql_variant version.
P.S.
I run some tests on data-set of 350k values, and seems that performance is the same, sql_variant is tiny bit faster, but I believe it's just jitters.
But any way IIF version is 10x times faster!!!
I haven't tested inline CASE WHEN but basically for t-sql IIF is same as case, and iif get's converted by optimizer to case expression.
The fact that IIF is translated into CASE also has an impact on other
aspects of the behavior of this function.
CONCLUSION: It's faster to use IIF if performance matters, but for prototyping, or if code clarity is more needed, and no big calculations are involved, provided function can be used.
I was intending to add comment to @ed-avis answer, but unable to do so, due to lack of reputation, so posting this as extension to his answer.
I've eliminated disadvantage of "Annoyingly you have to make separate functions for each data type." Using SQL_VARIANT.
Here is my implementation:
CREATE OR ALTER FUNCTION my_least(@a SQL_VARIANT, @b SQL_VARIANT)
returns SQL_VARIANT
with schemabinding
as
begin
return case when @a <= @b then @a
when @b < @a then @b
WHEN @a IS NULL THEN @b
WHEN @b IS NULL THEN @a
else null
end
END;
Also this function handles NULLs like postgresql version.
This function could be added to DB for convenience, but it's 10 times slower, than using built in IIF. My tests shows, that such function with exact type (datetime) performs same as sql_variant version.
P.S.
I run some tests on data-set of 350k values, and seems that performance is the same, sql_variant is tiny bit faster, but I believe it's just jitters.
But any way IIF version is 10x times faster!!!
I haven't tested inline CASE WHEN but basically for t-sql IIF is same as case, and iif get's converted by optimizer to case expression.
The fact that IIF is translated into CASE also has an impact on other
aspects of the behavior of this function.
CONCLUSION: It's faster to use IIF if performance matters, but for prototyping, or if code clarity is more needed, and no big calculations are involved, provided function can be used.
edited 7 mins ago
Colin 't Hart
6,66182634
6,66182634
answered Jan 1 at 23:19
Bogdan MartBogdan Mart
195
195
1
You say that "sqlvariant is tiny bit faster" and that "IIF version is 10x times faster". faster than what?
– ypercubeᵀᴹ
Jan 2 at 2:18
Sql variant ver is around same speed as concreete version, like provided by another answer. In my test it was 80ms fater (out from 15sec), I assumme that just statistics error. And usingiif(a<b, a, b)is 10 times faster as any user defined function.
– Bogdan Mart
Jan 2 at 2:21
To be clear, I used my code with sql_variant replaced with datetime, as second function. After tests it seems that sql_variant don't add any overhead, but user defined functions are way slower, than built-in
– Bogdan Mart
Jan 2 at 2:22
But is any of these functions - includingIIF()- faster than using aCASEexpression? My point is, that since you went into the trouble of performance testing, you should test all the suggested methods/answers.
– ypercubeᵀᴹ
Jan 2 at 2:26
1
@yper-crazyhat-cubeᵀᴹ updated answer. Won't edit it more, just wanted to add comment regarding sql_variant to ed-avis's answer, but due to lack of pints had to write expanded answer :-)
– Bogdan Mart
Jan 3 at 0:42
|
show 3 more comments
1
You say that "sqlvariant is tiny bit faster" and that "IIF version is 10x times faster". faster than what?
– ypercubeᵀᴹ
Jan 2 at 2:18
Sql variant ver is around same speed as concreete version, like provided by another answer. In my test it was 80ms fater (out from 15sec), I assumme that just statistics error. And usingiif(a<b, a, b)is 10 times faster as any user defined function.
– Bogdan Mart
Jan 2 at 2:21
To be clear, I used my code with sql_variant replaced with datetime, as second function. After tests it seems that sql_variant don't add any overhead, but user defined functions are way slower, than built-in
– Bogdan Mart
Jan 2 at 2:22
But is any of these functions - includingIIF()- faster than using aCASEexpression? My point is, that since you went into the trouble of performance testing, you should test all the suggested methods/answers.
– ypercubeᵀᴹ
Jan 2 at 2:26
1
@yper-crazyhat-cubeᵀᴹ updated answer. Won't edit it more, just wanted to add comment regarding sql_variant to ed-avis's answer, but due to lack of pints had to write expanded answer :-)
– Bogdan Mart
Jan 3 at 0:42
1
1
You say that "sqlvariant is tiny bit faster" and that "IIF version is 10x times faster". faster than what?
– ypercubeᵀᴹ
Jan 2 at 2:18
You say that "sqlvariant is tiny bit faster" and that "IIF version is 10x times faster". faster than what?
– ypercubeᵀᴹ
Jan 2 at 2:18
Sql variant ver is around same speed as concreete version, like provided by another answer. In my test it was 80ms fater (out from 15sec), I assumme that just statistics error. And using
iif(a<b, a, b) is 10 times faster as any user defined function.– Bogdan Mart
Jan 2 at 2:21
Sql variant ver is around same speed as concreete version, like provided by another answer. In my test it was 80ms fater (out from 15sec), I assumme that just statistics error. And using
iif(a<b, a, b) is 10 times faster as any user defined function.– Bogdan Mart
Jan 2 at 2:21
To be clear, I used my code with sql_variant replaced with datetime, as second function. After tests it seems that sql_variant don't add any overhead, but user defined functions are way slower, than built-in
– Bogdan Mart
Jan 2 at 2:22
To be clear, I used my code with sql_variant replaced with datetime, as second function. After tests it seems that sql_variant don't add any overhead, but user defined functions are way slower, than built-in
– Bogdan Mart
Jan 2 at 2:22
But is any of these functions - including
IIF() - faster than using a CASE expression? My point is, that since you went into the trouble of performance testing, you should test all the suggested methods/answers.– ypercubeᵀᴹ
Jan 2 at 2:26
But is any of these functions - including
IIF() - faster than using a CASE expression? My point is, that since you went into the trouble of performance testing, you should test all the suggested methods/answers.– ypercubeᵀᴹ
Jan 2 at 2:26
1
1
@yper-crazyhat-cubeᵀᴹ updated answer. Won't edit it more, just wanted to add comment regarding sql_variant to ed-avis's answer, but due to lack of pints had to write expanded answer :-)
– Bogdan Mart
Jan 3 at 0:42
@yper-crazyhat-cubeᵀᴹ updated answer. Won't edit it more, just wanted to add comment regarding sql_variant to ed-avis's answer, but due to lack of pints had to write expanded answer :-)
– Bogdan Mart
Jan 3 at 0:42
|
show 3 more comments
Thanks for contributing an answer to Database Administrators Stack Exchange!
- 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%2fdba.stackexchange.com%2fquestions%2f187090%2fdoes-sql-server-support-greatest-and-least-if-not-what-is-the-common-workaround%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