Assuming you haven't fallen prey to any of the quirks in ISNUMERIC()
like ISNUMERIC(',')
, I think you've fallen into the same problem described here. As that poster so eloquently put it, "order of declaration does not imply order of execution".
In other words, just because you say
CASE WHEN ISNUMERIC(c) = 1
THEN (CASE WHEN c LIKE '%.%'
THEN CAST(c AS FLOAT)
ELSE c + '.00' END)
ELSE '0.00' END
does not mean that ISNUMERIC(c) = 1
will control how CAST(c AS FLOAT)
is executed. The only way to control execution order is to use a different clause entirely. In this case, you should use the WHERE clause and UNION ALL the results.
Also, note that CASE WHEN c LIKE '%.%' THEN CAST(c AS FLOAT) ELSE c + '.00' END
is functionally identical to just saying CAST(c AS FLOAT)
because only one data type is allowed per column.
That means you need to do this:
SELECT a,
b,
CAST(0.00 AS FLOAT)
FROM table_name
WHERE b = 17
AND ISNUMERIC(c) <> 1
UNION ALL
SELECT a,
b,
CAST(c AS FLOAT)
FROM table_name
WHERE b = 17
AND ISNUMERIC(c) = 1
Beyond that, consider if you really want FLOAT
. It's not a precise data type, and it's fairly uncommon that precision is not a requirement of an RDBMS. If you need precision, use NUMERIC
or DECIMAL
.