• Home
  • Posts RSS
  • Comments RSS
  • Edit
Blue Orange Green Pink Purple

Welcome

Just a place for me to spew some relatively random (relative to being mostly IT related) stuff for those who might be Googling for a solution or an idea.

SQL strangeness

I have a table new_table that has 2 cols: ID - nvarchar (5), and Value - nvarchar(20)
the table has 7 a rows:
ID, Value
E1, yes
E2, 32.3
E3, 9
R1, 151
R2 40
R3, 20
R4, 99

I need to get the count of the rows where the values are in (R1, R2) and Value >= 151

If I select count(*) from new_data where ID in (R1, R2) it returns '2'
If I select value from new_data where ID in (R1, R2) it returns 151 and 49
If I select value from new_data where ID in (R1, R2) and Value >=151 it tells me it can't convert 'yes' to integer.

Tried making a CTE to tempData where ID in (R1, R2) then doing a select count(*) from tempData where Value >= 151 I get the same error.

However, select count(*) from tempData gives me the correct 2 and select value from tempData gives me 151 and 40 as you would expect. Any ideas?

Tried adding a convert, isnumeric, etc, no change.

The real issue is why is it even seeing the "yes" row when I add in the Value >=151 condition since any rows without valid values should have been filtered out of the tempData table?
Read More 5 comments | Posted by John Voorhis | edit post

5 comments

  1. Peter Schott on February 10, 2010 at 4:42 PM

    Had to double-check this to see that I wasn't on a SQL Server site. Your problem is that SQL is trying to do an implicit conversion of all values and throws an error when it hits "yes".

    You may want to try:
    CASE WHEN ISNUMERIC(Value) = 1 THEN CAST(Value as int) ELSE 0 END as Value

    That will force your non-numeric value data to evaluate to 0 and treat the rest as int (or whatever mixture of float/int/numeric you may need).

    I'm assuming this is for one of those custom field table setups that are allowed in some systems. If so, I'd even consider creating a view out of it and saving it for that custom field, assuming that this particular field will always have numeric values.

     
  2. John Voorhis on February 10, 2010 at 4:53 PM

    Hi Peter -

    MS SQL 2005. I tried that exact code previously - just shifted the error to a decimal value.

     
  3. Peter Schott on February 10, 2010 at 5:28 PM

    Not sure if the last comment posted or not. Have you tried pulling out all of the values for that particular custom field into a temp table and working with just that subset? Maybe cast as a numeric instead of int and/or add another case statement for decimals?

     
  4. Stephen Horne (Bluedog67) on February 10, 2010 at 5:36 PM

    John,

    What I think is going on is the Query Optimizer is taking your queries as suggestions only - you are trying to be explicit about "do this first then do this" but it is ignoring you and trying to optimize the query. In doing so at some point it is looking at your Value >= 151 test against the whole table and sees the non-numeric value and chokes. But I could be wrong. I was able to code a possible non-UDF solution that may work for you.

    You may try the following (developed and tested on SQL 2008 only. I tested with Compatibility Level set to SQL 2005 and still worked.):

    SELECT *
    FROM
    (SELECT ID,
    Value OriginalValue,
    CASE WHEN ISNUMERIC(Value) = 1 THEN CAST(Value AS decimal(5, 1))
    ELSE NULL END ValueNumeric,
    CASE WHEN ISNUMERIC(Value) = 0 THEN Value
    ELSE NULL END ValueCharacter
    FROM new_data) X
    WHERE X.ID IN ('R1', 'R2')
    AND X.ValueNumeric >= 121

    Please let me know if this works or not. I have a couple more ideas if this doesn't.

    Thanks,
    Stephen

     
  5. jonmcrawford on February 11, 2010 at 10:52 AM

    Did Stephen's comment answer why it happened for you? As Stephen said, the SQL is being evaluated for each value in your column in order to decide if it should be included (prior to being executed), and 'yes' >= '151' is not defined, so it chokes before it returns something.

    Stephen, your solution should work on 2000 also, since you're using a derived table.

    To me, it looks like a design flaw, if you're planning on storing numbers then use a corresponding datatype (int/float/decimal/whatever works best). This may not be possible if you can't change the design, and you'd need to clean your rows with 'yes'. Once you did that, your original query would work just fine.

    Hope that helps,

    Jon

     


Post a Comment

Newer Post Older Post Home

Glyphs

  • About
      I'm a supervisor in IT consulting for a top-5 accounting and consulting firm, as well as the Chair of the IT and Webcast Committees @ Tenth Presbyterian Church.
  • Search






    • Home
    • Posts RSS
    • Comments RSS
    • Edit

    © Copyright Glyphs. All rights reserved.
    Designed by FTL Wordpress Themes | Bloggerized by FalconHive.com
    brought to you by Smashing Magazine

    Back to Top