Just curious, what are your SQL pet peeves ?

  • A recent post just reminded me of one of my greatest pet peeves... people that correct your English, spelling, or punctuation on forum posts. I've also found that they usually do that when they consider it beneath them to defend any point that they've been trying to make or can't actually do so.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • I'm not sure if I'm even allowed to have a pet peeve as I have only been doing this a year. However one thing that has bothered me is every time I go into a certain developers queries I have noticed that they constantly do

    a ISNULL check on Non-Nullable columns. Actaully they seem to apply it to every column without discretion.

    Example: ISNULL(col1,'0') Where col1's constraint/properties does not allow nulls to begin with.

    Is this even a legit complaint? I guess what irritates me is the fact that they never seem to check the column properties before coding all of that clutter. Which means in my mind that they probably don't check a great many other things.

    ***SQL born on date Spring 2013:-)

  • thomashohner (6/7/2014)


    I'm not sure if I'm even allowed to have a pet peeve as I have only been doing this a year. However one thing that has bothered me is every time I go into a certain developers queries I have noticed that they constantly do

    a ISNULL check on Non-Nullable columns. Actaully they seem to apply it to every column without discretion.

    Example: ISNULL(col1,'0') Where col1's constraint/properties does not allow nulls to begin with.

    Is this even a legit complaint? I guess what irritates me is the fact that they never seem to check the column properties before coding all of that clutter. Which means in my mind that they probably don't check a great many other things.

    Very fortunately, SQL Server will frequently ignore an ISNULL on a non-nullable column but I agree... it makes for unnecessary clutter. And I also agree that doing things by rote like this means that haven't checked on a whole lot of other things in the name of "getting it done". It's part of the reason why there are so many performance problems.

    Although nullability works differently for most applications outside of the defaults for SSMS (which explains why some front-enders do the following), a couple of my "favorite" mistakes, even when a column is nullable, are...

    WHERE ISNULL(somecol,' ') <> ' '

    ... or ...

    WHERE ISNULL(somecol,0) <> 0

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Very fortunately, SQL Server will frequently ignore an ISNULL on a non-nullable column but I agree... it makes for unnecessary clutter. And I also agree that doing things by rote like this means that haven't checked on a whole lot of other things in the name of "getting it done". It's part of the reason why there are so many performance problems.

    Although nullability works differently for most applications outside of the defaults for SSMS (which explains why some front-enders do the following), a couple of my "favorite" mistakes, even when a column is nullable, are...

    WHERE ISNULL(somecol,' ') <> ' '

    ... or ...

    WHERE ISNULL(somecol,0) <> 0

    Your examples are exactly some of the things I see in these queries.

    ***SQL born on date Spring 2013:-)

  • Jeff, I'm so sorry this may be a very dumb question but in your examples when the column is NULLABLE why is that expression wrong? I just tested it on a NULLABLE column and it seems to work. However I do know what seems to work and what works are two different things. Sorry about my confusion. Looking for some insight and education on this.

    Thomas

    This is what I ran:

    USE Thomas_Test

    CREATE TABLE NULL_TEST (Column1 VARCHAR(5) NOT NULL, Column2 Numeric(2) NULL)

    GO

    INSERT INTO NULL_TEST VALUES ('test1', 2),('test3',null),('test4','5'),('test5','6')

    GO

    SELECT *

    FROM NULL_TEST

    WHERE ISNULL(Column2,0) <> 0

    SELECT *

    FROM NULL_TEST

    GO

    DROP TABLE NULL_TEST

    ***SQL born on date Spring 2013:-)

  • thomashohner (6/7/2014)


    Jeff, I'm so sorry this may be a very dumb question but in your examples when the column is NULLABLE why is that expression wrong? I just tested it on a NULLABLE column and it seems to work. However I do know what seems to work and what works are two different things. Sorry about my confusion. Looking for some insight and education on this.

    Thomas

    This is what I ran:

    USE Thomas_Test

    CREATE TABLE NULL_TEST (Column1 VARCHAR(5) NOT NULL, Column2 Numeric(2) NULL)

    GO

    INSERT INTO NULL_TEST VALUES ('test1', 2),('test3',null),('test4','5'),('test5','6')

    GO

    SELECT *

    FROM NULL_TEST

    WHERE ISNULL(Column2,0) <> 0

    SELECT *

    FROM NULL_TEST

    GO

    DROP TABLE NULL_TEST

    Added another query for you to look at.

    CREATE TABLE NULL_TEST (Column1 VARCHAR(5) NOT NULL, Column2 Numeric(2) NULL)

    GO

    INSERT INTO NULL_TEST VALUES ('test1', 2),('test3',null),('test4','5'),('test5','6')

    GO

    SELECT *

    FROM NULL_TEST

    WHERE ISNULL(Column2,0) <> 0

    SELECT *

    FROM NULL_TEST

    WHERE Column2 <> 0

    SELECT *

    FROM NULL_TEST

    GO

    DROP TABLE NULL_TEST;

  • Now I'm thoroughly confused? Why does that work? I thought NULL wasn't equal to anything. :blush:

    ***SQL born on date Spring 2013:-)

  • thomashohner (6/7/2014)


    Now I'm thoroughly confused? Why does that work? I thought NULL wasn't equal to anything. :blush:

    Not only is it not equal to anything, it also is not unequal to anything either.

    But I suspect that the issue Jeff was getting at was that "where isnull(col,0) <> 0) is presumably intended to pass all rows which don't have null in that column but if doesn't pass rows which are not null if they just ha[en to have 0 in that column, so as a way of passing all rows which don't have null in col it just doesn't work.

    Tom

  • Further Lynn's demonstration, here are few different ways the SQL Server handles NULL test (using Lynn's data).

    😎

    select * from

    (

    SELECT Column1, coalesce(Column2,0.0) as Column2

    FROM NULL_TEST

    ) as x where x.Column2 <> 0

    /*

    [Expr1003] = Scalar Operator(CASE WHEN [tempdb].[dbo].[NULL_TEST].[Column2] IS NOT NULL THEN CONVERT_IMPLICIT(numeric(3,1),[tempdb].[dbo].[NULL_TEST].[Column2],0) ELSE (0.0) END)

    */

    select * from

    (

    SELECT Column1, coalesce(Column2,0.0) as Column2

    FROM NULL_TEST

    ) as x where x.Column2 = 0

    /*

    [Expr1003] = Scalar Operator(CASE WHEN [tempdb].[dbo].[NULL_TEST].[Column2] IS NOT NULL THEN CONVERT_IMPLICIT(numeric(3,1),[tempdb].[dbo].[NULL_TEST].[Column2],0) ELSE (0.0) END)

    */

    select * from

    (

    SELECT Column1, isnull(Column2,0.0) as Column2

    FROM NULL_TEST

    ) as x where x.Column2 = 0

    /*[Expr1003] = Scalar Operator(isnull([tempdb].[dbo].[NULL_TEST].[Column2],(0.)))

    */

    select * from

    (

    SELECT Column1, isnull(Column2,0.0) as Column2

    FROM NULL_TEST

    ) as x where x.Column2 != 0

    /*

    [Expr1003] = Scalar Operator(isnull([tempdb].[dbo].[NULL_TEST].[Column2],(0.)))

    */

    select * from

    (

    SELECT Column1, isnull(Column2,0.0) as Column2

    FROM NULL_TEST

    ) as x where x.Column2 <> 0

    /*

    [Expr1003] = Scalar Operator(CASE WHEN [tempdb].[dbo].[NULL_TEST].[Column2] IS NOT NULL THEN CONVERT_IMPLICIT(numeric(3,1),[tempdb].[dbo].[NULL_TEST].[Column2],0) ELSE (0.0) END)

    */

    SELECT

    Column1

    ,ISNULL(Column2,0) AS Column2

    FROM NULL_TEST

    WHERE Column2 <> 0

    /*

    [Expr1003] = Scalar Operator([tempdb].[dbo].[NULL_TEST].[Column2])

    */

    SELECT

    Column1

    ,CASE

    WHEN Column2 IS NULL THEN 0

    ELSE Column2

    END AS Column2

    FROM NULL_TEST

    WHERE Column2 <> 0

    /*

    [Expr1003] = Scalar Operator(CASE WHEN [tempdb].[dbo].[NULL_TEST].[Column2] IS NULL THEN (0.) ELSE [tempdb].[dbo].[NULL_TEST].[Column2] END)

    */

    SELECT

    Column1

    ,CASE

    WHEN Column2 IS NULL THEN 0

    ELSE Column2

    END AS Column2

    FROM NULL_TEST

    WHERE Column2 = 0

    /*

    [Expr1003] = Scalar Operator(CASE WHEN [tempdb].[dbo].[NULL_TEST].[Column2] IS NULL THEN (0.) ELSE [tempdb].[dbo].[NULL_TEST].[Column2] END)

    */

    SELECT

    Column1

    ,CASE

    WHEN Column2 IS NULL THEN 0

    ELSE Column2

    END AS Column2

    FROM NULL_TEST

    WHERE Column2 != 0

    /*

    [Expr1003] = Scalar Operator(CASE WHEN [tempdb].[dbo].[NULL_TEST].[Column2] IS NULL THEN (0.) ELSE [tempdb].[dbo].[NULL_TEST].[Column2] END)

    */

  • thomashohner (6/7/2014)


    Jeff, I'm so sorry this may be a very dumb question but in your examples when the column is NULLABLE why is that expression wrong? I just tested it on a NULLABLE column and it seems to work. However I do know what seems to work and what works are two different things. Sorry about my confusion. Looking for some insight and education on this.

    Thomas

    The code does NOT come up with the wrong answer. As you point out, it comes up with the technically accurate answer. So, let's look at your WHERE clause...

    WHERE ISNULL(Column2,0) <> 0

    What does that code actually do?

    Quite literally, is says that it should treat all nulls as if they had the value of 0 and then return things that don't have a value of 0.

    Now for the question behind the magic. If the WHERE clause is written like the following...

    WHERE Column2 <> 0

    ... why doesn't it return the rows where Column2 is NULL?

    Once you figure that out, then tell me why this...

    WHERE ISNULL(Column2,0) <> 0

    ... is worse than this ...

    WHERE Column2 <> 0

    I'm not giving the answer directly because you'll remember this forever if you have your own "Eureka" momement.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Oh dear god this will consume me tomorrow trying to figure this out. But I agree letting me try to do this on my own will make it stick. I'm glad I didn't get scared and posted what I did not understand. I just may learn something here. I will get back to you fine gents when I have a answer!

    ***SQL born on date Spring 2013:-)

  • Okay I really feel stupid after looking at this some more. :blush:

    WHERE Column <>0

    This "works" because NULLS are part of the three valued predicate logic. True, False and Unknown. NULLS are neither equal nor not equal to anything so they are excluded anytime the predication is =,<>

    Hence this will only return values <> 0 since NULLS are part of the Unknown predicate they don't return either.

    So when predicating to True, False and Unknown are excluded. When predicating to False, True and Unknown are excluded.

    As far as WHERE ISNULL(Column1, 0) <> 0

    This is not as good because calling on a function in the WHERE clause makes a Index useless. Does this also mean that ISNULL is processed like a SCALAR function a row at a time?

    I'm sure there's more and I'll continue researching. But am I getting warmer?

    ***SQL born on date Spring 2013:-)

  • thomashohner (6/8/2014)


    Okay I really feel stupid after looking at this some more. :blush:

    I very much appreciate your humility here because it's one of those things that I hold most dear in Developers and DBAs. It sometimes makes a huge difference in being "just" a DBA and being an "Exceptional DBA". But, there's no need to feel "stupid" here. It's something that everyone has a problem with at one time or another, present company (ME!) being no exception.

    WHERE Column <>0

    This "works" because NULLS are part of the three valued predicate logic. True, False and Unknown. NULLS are neither equal nor not equal to anything so they are excluded anytime the predication is =,<>

    Hence this will only return values <> 0 since NULLS are part of the Unknown predicate they don't return either.

    So when predicating to True, False and Unknown are excluded. When predicating to False, True and Unknown are excluded.

    As far as WHERE ISNULL(Column1, 0) <> 0

    This is not as good because calling on a function in the WHERE clause makes a Index useless. Does this also mean that ISNULL is processed like a SCALAR function a row at a time?

    Heh... I'll say it for you... EUREKA! 🙂

    I'm sure there's more and I'll continue researching. But am I getting warmer?

    There always will be and yes, you've pretty much nailed what I was getting at. Even when working with "NULL comparisons" today, I still setup small tests to make sure that NULLs aren't going to bite me because I still make mistakes if I'm in a hurry. The tests not only slow me down to think about it, they prove to me that the criteria that I'm about to drop into production will actually work as expected. For example of this case...

    WITH

    cteNullTest(N) AS

    (

    SELECT -2 UNION ALL

    SELECT -1 UNION ALL

    SELECT 0 UNION ALL

    SELECT 1 UNION ALL

    SELECT 2 UNION ALL

    SELECT NULL

    )

    SELECT *

    FROM cteNullTest

    WHERE N <> 0

    ;

    ... and I KNOW I'd make such mistakes without such a test because I've done so in an area just as critical as making such a mistake in prod... on forums where people rely on stuff like this being right. :blush:

    There is one thing, though. Once I've spent the time to figure out such a thing, I remember that others may not spend the time to figure things out or they just might not know about how NULLs work and don't work. With that in mind, I take the time to write some "horribly complicated code" that a lot of people are dead set against because it "slows them down too much" even though it makes the intent of the code crystal clear for those that don't understand NULLs. Heh... you ready for this?

    WHERE Column <> 0 --Is NOT NULL and is NOT ZERO

    😛

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Thanks for the feedback Jeff,

    This became a very valuable lesson in my eyes. I am already wanting to go down to the office and open up some of my previous queries because of this understanding of NULLS. I want to double check my logic where NULLS may play a role.

    I have read several SQl books most aimed at beginners to intermediate levels. However only the most recent that I just started reading explained NULLS as part of the 3 part predicate logic in detail. The others just implied it by saying it doesn't equal nor not equal.

    It was a definite aha moment:-D

    P.S sorry for jacking the thread on a side tangent:-P

    ***SQL born on date Spring 2013:-)

  • Luis Cazares (6/6/2014)


    djj (6/6/2014)


    And I'm not obfuscating the names. :crazy:

    But the meaning is obvious

    Ambivalently named table that will take 60 years to recover from the mental scarring when trying to deliver

Viewing 15 posts - 166 through 180 (of 272 total)

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