May 3, 2010 at 9:48 am
Nice question - great explanation Hugo.
Jason...AKA CirqueDeSQLeil
_______________________________________________
I have given a name to my pain...MCM SQL Server, MVP
SQL RNNR
Posting Performance Based Questions - Gail Shaw[/url]
Learn Extended Events
May 3, 2010 at 9:55 am
Hugo Kornelis (5/3/2010)
Using ISNULL can work around this - although the result is admittedly not trivial to understand:AND NULLIF(Column1, Column2) IS NULL
AND NULLIF(Column2, Column1) IS NULL
:w00t: Hugo!!! Yuk! :sick:
Paul White
SQLPerformance.com
SQLkiwi blog
@SQL_Kiwi
May 3, 2010 at 10:09 am
Paul White NZ (5/3/2010)
Hugo Kornelis (5/3/2010)
Using ISNULL can work around this - although the result is admittedly not trivial to understand:AND NULLIF(Column1, Column2) IS NULL
AND NULLIF(Column2, Column1) IS NULL
:w00t: Hugo!!! Yuk! :sick:
:Whistling:
May 3, 2010 at 10:15 am
Paul White NZ (5/3/2010)
Hugo Kornelis (5/3/2010)
Using ISNULL can work around this - although the result is admittedly not trivial to understand:AND NULLIF(Column1, Column2) IS NULL
AND NULLIF(Column2, Column1) IS NULL
:w00t: Hugo!!! Yuk! :sick:
Think I have to go with Paul on this one. For me,
WHERE Column18 > 27
AND (Column1 = Column2 OR (Column1 IS NULL AND Column2 IS NULL))
is easier to write, to read, and to understand quickly (and should perform as well or better) than:
WHERE Column18 > 27
AND NULLIF(Column1, Column2) IS NULL
AND NULLIF(Column2, Column1) IS NULL
So I don't see any value to NULLIF in this scenario.
As for me, I read the question, understood the logic, did the process, decided on NULL, then clicked on 0. Steve, when are you going to get that module that scores us on what we meant to choose, rather than what we actually chose...? 😛
May 3, 2010 at 11:08 am
I think it is also important to understand what is going on underneath the hood, when NULLIF is used. Unbeknownst to some, NULLIF is actually a case expression under the hood, which means it is subject to data type precedence. The second value is not always implicitly converted to the data type of the first value. Whichever side has the less data type precedence will be converted to the other data type. This can cause implict conversion errors, if the columns cannot be converted to the higher data type.
e.g.
DECLARE @t TABLE(fl int);
INSERT INTO @t VALUES (0);
DECLARE @var CHAR(1),
@var2 DATETIME
SET @var = ''
SET @var2 = GETDATE()
select nullif(fl, @var)
FROM @t
--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [fl]=CONVERT_IMPLICIT(int,[@var],0) THEN NULL ELSE [fl] END))
select nullif(fl, @var2)
FROM @t
--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN CONVERT_IMPLICIT(datetime,[fl],0)=[@var2] THEN NULL ELSE [fl] END))
May 3, 2010 at 2:30 pm
Interesting question - thanks.
The explanation led me to wonder what other character CAST() would return with 0. I've found two:
select cast('+' as smallint)
select cast('-' as smallint)
But why should a negative or positive sign return a zero?
The greatest enemy of knowledge is not ignorance, it is the illusion of knowledge. - Stephen Hawking
May 3, 2010 at 7:58 pm
I'm pretty sure Hugo posted the NULLIF 'solution' as a bit of fun - though the idea behind it is very clever and worth posting just for that.
My comment was intended to be humourous as much as anything else - I laughed when I saw Hugo's :Whistling: reply.
(I don't disagree with anything you wrote by the way)
Paul
Paul White
SQLPerformance.com
SQLkiwi blog
@SQL_Kiwi
May 4, 2010 at 12:03 am
Adam Haines (5/3/2010)
I think it is also important to understand what is going on underneath the hood, when NULLIF is used. Unbeknownst to some, NULLIF is actually a case expression under the hood, which means it is subject to data type precedence. The second value is not always implicitly converted to the data type of the first value. Whichever side has the less data type precedence will be converted to the other data type. This can cause implict conversion errors, if the columns cannot be converted to the higher data type.e.g.
DECLARE @t TABLE(fl int);
INSERT INTO @t VALUES (0);
DECLARE @var CHAR(1),
@var2 DATETIME
SET @var = ''
SET @var2 = GETDATE()
select nullif(fl, @var)
FROM @t
--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [fl]=CONVERT_IMPLICIT(int,[@var],0) THEN NULL ELSE [fl] END))
select nullif(fl, @var2)
FROM @t
--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN CONVERT_IMPLICIT(datetime,[fl],0)=[@var2] THEN NULL ELSE [fl] END))
thats called having red meat with cold beer on beach....PERFECT fruit for this thread.
-------Bhuvnesh----------
I work only to learn Sql Server...though my company pays me for getting their stuff done;-)
May 4, 2010 at 7:24 am
Paul White NZ (5/3/2010)
@sknox:I laughed when I saw Hugo's :Whistling: reply.
Paul
So did I ... AFTER I'd already posted my reply. Oh, the wonders of asynchronous operations!
May 4, 2010 at 7:36 am
Great question. I learned that I should read more carefully. This question was about NULLIF (which I had never learned), not ISNULL! :blush:
Thanks,
webrunner
-------------------
A SQL query walks into a bar and sees two tables. He walks up to them and asks, "Can I join you?"
Ref.: http://tkyte.blogspot.com/2009/02/sql-joke.html
May 6, 2010 at 2:46 pm
Thanks for the info Hugo. I can now see where it would be useful in a couple of queries I have for some reports - where I was getting a potential division by zero, depending on the input data. I seem to remember putting a rather inelegant solution (in comparison) to handle it. Will have to revisit.
MARCUS. Why dost thou laugh? It fits not with this hour.
TITUS. Why, I have not another tear to shed;
--Titus Andronicus, William Shakespeare
November 7, 2010 at 4:46 pm
Awesome question. didn't know nullIf can be these much tricky...
Viewing 13 posts - 16 through 27 (of 27 total)
You must be logged in to reply to this topic. Login to reply