coalesce and nullif

  • LP-181697

    SSC Eights!

    Points: 966

    Comments posted to this topic are about the item coalesce and nullif

  • Oleg Netchaev

    SSCertifiable

    Points: 5156

    This is a very good question, thank you. Presence of nullif does not change anything though, so it is difficult to figure out why it is there. What I mean is that if the question is reduced to declaring and setting @C and @d only and the statements in question are then changed to

    select coalesce(@c, @d);

    select coalesce(@d, @C);

    the result will still be the same, the first statement will fail and the second one will run just fine. I guess that this is because of the major difference between the behavior of coalesce with 2 parameters and isnull function which I believe would execute both statements just fine: coalesce always returns the expression of the highest precedence data type regardless of the parameters' order while isnull returns the data type of the first parameter. In other words, coalesce tries to cast first occurrence of the not null as datetime (datetime is of higher precedence). This is why it fails in the first statement, the first not null is @C which is equal to 'test', it tries to cast 'test' as datetime and fails. The second statement has the first not null is @d which is a datetime already, so the second statement executes without error.

    Once again, thank you for an excellent question, I really enjoyed it.

    Oleg

  • hemang.patel

    Old Hand

    Points: 364

    Thanks for explain precedence logic. Now I understand it perfectly

  • Hugo Kornelis

    SSC Guru

    Points: 64645

    Thanks, Oleg, for the explanation of the difference between COALESCE and ISNULL. I was about to add it myself, since it is lacking in the question, but you beat me to it.

    And I agree with you that the NULLIF serves no apparent function here. Other than to obfuscate. (I knew that both COALESCE functions would return datetime; I then pondered for an extra minute to make really sure that the NULLIF does not affect the result at all; then gave the wrong answer because my not-yet awake brain thought both expression would try to convert 'Test' to the target data type).

    And for those who want to do some further reading:

    * Data type precedence: http://msdn.microsoft.com/en-us/library/ms190309.aspx

    * NULLIF: http://msdn.microsoft.com/en-us/library/ms177562.aspx

    * COALESCE: http://msdn.microsoft.com/en-us/library/ms190349.aspx

    * ISNULL (similar to, yet also different from COALESCE): http://msdn.microsoft.com/en-us/library/ms184325.aspx


    Hugo Kornelis, SQL Server/Data Platform MVP (2006-2016)
    Visit my SQL Server blog: https://sqlserverfast.com/blog/
    SQL Server Execution Plan Reference: https://sqlserverfast.com/epr/

  • vk-kirov

    SSCertifiable

    Points: 7686

    Nice question.

    OFF

    I would like thanks my coorker...

    What does the word 'coorker' mean? Is it a typo and needs to be 'coworker'?

  • Arsi Salo

    Ten Centuries

    Points: 1313

    Nice QotD. It would have been more educational with third section

    select @C = 'test', @c1 = null, @d = '01/01/10', @d1 = '01/01/10',

    which brings nullif into fray...

  • ronmoses@gmail.com

    SSCarpal Tunnel

    Points: 4480

    This is a great question, and I'm proud that I managed to work out the correct answer once I realized the first statement was going to try and cast 'test' as a datetime. And then I clicked the wrong option and lost the points. Yay for me! 😀

    -----
    a haiku...

    NULL is not zero
    NULL is not an empty string
    NULL is the unknown

  • LP-181697

    SSC Eights!

    Points: 966

    vk-kirov (6/23/2010)


    Nice question.

    OFF

    I would like thanks my coorker...

    What does the word 'coorker' mean? Is it a typo and needs to be 'coworker'?

    It means coworker. It was typo

  • WayneS

    SSC Guru

    Points: 95328

    Oleg, thanks for the explanation. Hugo, thanks for the links, especially for the data type precedence. Between the two of you'll, this is the explanation that the question should have had.

    Wayne
    Microsoft Certified Master: SQL Server 2008
    Author - SQL Server T-SQL Recipes[/url]


    If you can't explain to another person how the code that you're copying from the internet works, then DON'T USE IT on a production system! After all, you will be the one supporting it!
    Links: For better assistance in answering your questions[/url], How to ask a question, Performance Problems[/url], Common date/time routines,
    CROSS-TABS and PIVOT tables Part 1[/url] & [url url=http://www

  • forjonathanwilson

    SSC Enthusiast

    Points: 139

    null date can be cast as null string, but not the other way, interesting.:hehe:

  • Hugo Kornelis

    SSC Guru

    Points: 64645

    forjonathanwilson (6/23/2010)


    null date can be cast as null string, but not the other way, interesting.:hehe:

    This is not correct. A null string can be cast as date (result will be NULL). The problem starts when you try to case a non-null string as date - in that case, the string must evaluate to a valid date. And obviously, the string 'Test' does not qualify there.


    Hugo Kornelis, SQL Server/Data Platform MVP (2006-2016)
    Visit my SQL Server blog: https://sqlserverfast.com/blog/
    SQL Server Execution Plan Reference: https://sqlserverfast.com/epr/

  • forjonathanwilson

    SSC Enthusiast

    Points: 139

    Hugo Kornelis (6/23/2010)


    forjonathanwilson (6/23/2010)


    null date can be cast as null string, but not the other way, interesting.:hehe:

    This is not correct. A null string can be cast as date (result will be NULL). The problem starts when you try to case a non-null string as date - in that case, the string must evaluate to a valid date. And obviously, the string 'Test' does not qualify there.

    thanks for clarifying that for me. I also checked this myself after I made my irroneous assumption:

    declare @C varchar(10), @c1 varchar(10),

    @d datetime, @d1 datetime

    select @C = 'test', @c1 = null, @d = '1/1/10', @d1 = null

    select coalesce(nullif(@c,@c),nullif(@d,@d))

    select coalesce(nullif(@d,@d),nullif(@c,@c))

    where the results are compared null datetime to null string by coalesce, which completes just fine.

  • UMG Developer

    SSChampion

    Points: 13482

    Interesting question, thanks.

    Thanks Oleg for the explanation of why it happens, I think most people don't already know that, so it is very helpful.

  • ColdCoffee

    SSC-Dedicated

    Points: 39971

    Oleg and Hugo , thanks for the nice explanations and links.. nice question depicting the precedence of data-types... niceee.

  • Anam Verma

    SSCertifiable

    Points: 5365

    thanks for the good QOTD and explanation behind it.

Viewing 15 posts - 1 through 15 (of 19 total)

You must be logged in to reply to this topic. Login to reply