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







7















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 GREATEST LEAST

  • DB2 GREATEST LEAST

  • Oracle GREATEST LEAST


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?










share|improve this question































    7















    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 GREATEST LEAST

    • DB2 GREATEST LEAST

    • Oracle GREATEST LEAST


    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?










    share|improve this question



























      7












      7








      7


      3






      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 GREATEST LEAST

      • DB2 GREATEST LEAST

      • Oracle GREATEST LEAST


      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?










      share|improve this question
















      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 GREATEST LEAST

      • DB2 GREATEST LEAST

      • Oracle GREATEST LEAST


      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 1 '18 at 6:18









      Pang

      1316




      1316










      asked Sep 27 '17 at 18:57









      Evan CarrollEvan Carroll

      33.9k1080236




      33.9k1080236






















          6 Answers
          6






          active

          oldest

          votes


















          27














          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.






          share|improve this answer

































            9














            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





            share|improve this answer































              3














              This would be a good start -



              CASE WHEN A > B THEN A ELSE B END





              share|improve this answer
























              • 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



















              2














              LEAST equivalent:



              IIF(@a < @b, @a, @b)


              GREATEST equivalent:



              IIF(@a > @b, @a, @b)





              share|improve this answer



















              • 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














              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 least operator 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 plain case when @a <= @b then @a else @b end would 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.






              share|improve this answer

































                0














                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.






                share|improve this answer





















                • 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 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











                • 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





                  @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












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


                }
                });














                draft saved

                draft discarded


















                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









                27














                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.






                share|improve this answer






























                  27














                  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.






                  share|improve this answer




























                    27












                    27








                    27







                    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.






                    share|improve this answer















                    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.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    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

























                        9














                        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





                        share|improve this answer




























                          9














                          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





                          share|improve this answer


























                            9












                            9








                            9







                            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





                            share|improve this answer













                            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






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Sep 27 '17 at 22:10









                            David Browne - MicrosoftDavid Browne - Microsoft

                            12.7k732




                            12.7k732























                                3














                                This would be a good start -



                                CASE WHEN A > B THEN A ELSE B END





                                share|improve this answer
























                                • 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
















                                3














                                This would be a good start -



                                CASE WHEN A > B THEN A ELSE B END





                                share|improve this answer
























                                • 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














                                3












                                3








                                3







                                This would be a good start -



                                CASE WHEN A > B THEN A ELSE B END





                                share|improve this answer













                                This would be a good start -



                                CASE WHEN A > B THEN A ELSE B END






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                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



















                                • 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











                                2














                                LEAST equivalent:



                                IIF(@a < @b, @a, @b)


                                GREATEST equivalent:



                                IIF(@a > @b, @a, @b)





                                share|improve this answer



















                                • 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
















                                2














                                LEAST equivalent:



                                IIF(@a < @b, @a, @b)


                                GREATEST equivalent:



                                IIF(@a > @b, @a, @b)





                                share|improve this answer



















                                • 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














                                2












                                2








                                2







                                LEAST equivalent:



                                IIF(@a < @b, @a, @b)


                                GREATEST equivalent:



                                IIF(@a > @b, @a, @b)





                                share|improve this answer













                                LEAST equivalent:



                                IIF(@a < @b, @a, @b)


                                GREATEST equivalent:



                                IIF(@a > @b, @a, @b)






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                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














                                • 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











                                1














                                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 least operator 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 plain case when @a <= @b then @a else @b end would 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.






                                share|improve this answer






























                                  1














                                  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 least operator 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 plain case when @a <= @b then @a else @b end would 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.






                                  share|improve this answer




























                                    1












                                    1








                                    1







                                    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 least operator 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 plain case when @a <= @b then @a else @b end would 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.






                                    share|improve this answer















                                    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 least operator 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 plain case when @a <= @b then @a else @b end would 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.







                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Mar 27 '18 at 8:58

























                                    answered Mar 6 '18 at 10:35









                                    Ed AvisEd Avis

                                    1193




                                    1193























                                        0














                                        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.






                                        share|improve this answer





















                                        • 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 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











                                        • 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





                                          @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
















                                        0














                                        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.






                                        share|improve this answer





















                                        • 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 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











                                        • 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





                                          @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














                                        0












                                        0








                                        0







                                        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.






                                        share|improve this answer















                                        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.







                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








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











                                        • 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





                                          @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





                                          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











                                        • 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








                                        • 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


















                                        draft saved

                                        draft discarded




















































                                        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.




                                        draft saved


                                        draft discarded














                                        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





















































                                        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







                                        Popular posts from this blog

                                        Ronny Ackermann

                                        Köttigit

                                        MySQL 8.0.15 starts normally but any connection hangs