|
|
|
Grasshopper
      
Group: General Forum Members
Last Login: Thursday, November 18, 2010 8:24 AM
Points: 12,
Visits: 85
|
|
|
|
|
|
Mr or Mrs. 500
      
Group: General Forum Members
Last Login: Wednesday, April 03, 2013 10:05 PM
Points: 584,
Visits: 1,571
|
|
This QotD raises a point I'm always having to remind developers about, and I guess SQL guys can also do with a reminder from time to time.
However, my 2 cents is rather than... declare @s char(4) select ISNULL(convert(varchar(16),@s),'Unknown')
...I would use... declare @s char(4) select coalesce(@s,'Unknown')
...which also has the ability to take more than 2 arguments.
S.
|
|
|
|
|
SSCoach
         
Group: General Forum Members
Last Login: Monday, May 20, 2013 1:07 PM
Points: 18,733,
Visits: 12,332
|
|
|
|
|
|
SSCoach
         
Group: General Forum Members
Last Login: Monday, May 20, 2013 1:07 PM
Points: 18,733,
Visits: 12,332
|
|
|
|
|
|
Grasshopper
      
Group: General Forum Members
Last Login: Thursday, November 18, 2010 8:24 AM
Points: 12,
Visits: 85
|
|
It's also interesting that coalesce behaves a different way from isnull.
My point in giving the isnull/convert formulation was to show how to make isnull behave in the way you might expect. I wasn't particularly recommending it.
Can anyone give an account of why the semantics of isnull and coalesce (with two args) is different?
|
|
|
|
|
Hall of Fame
       
Group: General Forum Members
Last Login: Today @ 3:58 AM
Points: 3,191,
Visits: 4,149
|
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Today @ 5:38 AM
Points: 2,949,
Visits: 1,395
|
|
CirquedeSQLeil (3/30/2010) However, you will find that many prefer the isnull due to an increase in performance.
Do you have a supporting link or further information on the performance difference between ISNULL and COALESCE? I was unaware of any significant difference between the two?
----- @jameslean
|
|
|
|
|
SSCertifiable
       
Group: General Forum Members
Last Login: Today @ 12:02 PM
Points: 5,243,
Visits: 7,055
|
|
James Lean (3/31/2010)
CirquedeSQLeil (3/30/2010) However, you will find that many prefer the isnull due to an increase in performance.Do you have a supporting link or further information on the performance difference between ISNULL and COALESCE? I was unaware of any significant difference between the two? COALESCE is implemented as a quite literal implementation of its definition in the ANSI standard (which is: COALESCE(a, b, ...) is equivalent to CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... ELSE NULL END).
So if any of the arguments is a subquery, the implementation if COALESCE((subquery), ...) becomes CASE WHEN (subquery) IS NOT NULL THEN (subquery) ... ELSE NULL END. And the optimizer that sits a bit further down the line does apparently not realize that the two subqueries are identical, so it happily produces a plan that will evaluate the same subquery twice.
Without the subqueries, I have never witnessed a measurable performance difference.
Hugo Kornelis, SQL Server MVP Visit my SQL Server blog: http://sqlblog.com/blogs/hugo_kornelis
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Today @ 5:38 AM
Points: 2,949,
Visits: 1,395
|
|
Thanks Hugo. That would seem to be a very specific case, I wouldn't have thought it was a good reason to make a general case for using COALESCE over ISNULL.
Personally I do tend to use COALESCE, even with only two arguments. That way, if you do need to add more arguments in future you don't have to worry about changing it. Unless I do need to take advantage of the implicit CASTing to the first argument's type, in which case I'll use ISNULL.
As always, I suppose, "it depends".
----- @jameslean
|
|
|
|
|
SSChampion
        
Group: General Forum Members
Last Login: Today @ 5:10 PM
Points: 10,989,
Visits: 10,535
|
|
Hugo Kornelis (3/31/2010) So if any of the arguments is a subquery, the implementation if COALESCE((subquery), ...) becomes CASE WHEN (subquery) IS NOT NULL THEN (subquery) ... ELSE NULL END. That reminds me of a CASE construction like the following:
SELECT CASE CHECKSUM(NEWID()) % 3 + 1 WHEN 1 THEN 'One' WHEN 2 THEN 'Two' WHEN 3 THEN 'Three' ELSE 'WTF?' END
...which quite frequently hits the ELSE, and that surprises some people.
And the optimizer that sits a bit further down the line does apparently not realize that the two subqueries are identical, so it happily produces a plan that will evaluate the same subquery twice. Once expanded by the CASE, is it true to say that they are identical? It seems to me that the results are non-deterministic, so it would not be safe to collapse these evaluations. (One might argue that it would be safe at the SERIALIZABLE isolation level (or one of the row-versioning isolation levels), but the plan would not then be reusable).
I blame the expansion of the CASE - which is apparently a documented design decision. I can live with it, though.
Last thing: the optimizer does a great job at avoiding the extra subquery evaluations where possible. The plan produced is quite likely to feature a PassThrough expression on the joins, so that the subquery is not re-evaluated if a prior term in the COALESCE already produced a non-NULL value.
Paul White SQL Server MVP SQLblog.com @SQL_Kiwi
|
|
|
|