views:

168

answers:

4
DECLARE @table table(XYZ VARCHAR(8) , id int)

INSERT INTO @table
SELECT '4000', 1
UNION ALL
SELECT '3.123', 2
UNION ALL
SELECT '7.0', 3
UNION ALL
SELECT '80000', 4
UNION ALL
SELECT NULL, 5

Query:

SELECT CASE 
         WHEN PATINDEX('^[0-9]{1,5}[\.][0-9]{1,3}$', XYZ) = 0 THEN XYZ
         WHEN PATINDEX('^[0-9]{1,8}$',XYZ) = 0 THEN CAST(XYZ AS decimal(18,3))/1000
         ELSE NULL 
       END
  FROM @table

This part - CAST(XYZ AS decimal(18,3))/1000 doesn't divide the value.

It gives me more number of zeros after decimal instead of dividing it. (I even enclosed that in brackets and tried but same result).

Ex:2000/1000 = 2000.000000

Am I doing something wrong here? Are patindex expression parameters correct?

Expected result:
4.000
3.123
7.000
80.000

Do let me know if PATINDEX is not correct method to use? I'm trying to check if it is already decimal with 3 decimal points else i want to divide by 1000.

A: 

Dividing by 1000 will give you more zeros after the decimal

5.3 / 1000 = .0053
Nate Heinrich
nope, the PATINDEX he is using prevents values with a decimal point from being divided by 1000
CResults
lol my question is confusing will correct it, 2000/1000 = 2000.000000 is what I'm getting
rs
+1  A: 

try this, convert the entire CASE to decimal(18,3):

DECLARE @table table(XYZ VARCHAR(8) , id int)

INSERT INTO @table
SELECT '4000', 1
UNION ALL
SELECT '3.123', 2
UNION ALL
SELECT '7.0', 3
UNION ALL
SELECT '80000', 4
UNION ALL
SELECT NULL, 5


SELECT CONVERT(decimal(18,3),CASE --nothing changes within the CASE
                                 WHEN PATINDEX('^[0-9]{1,5}[\.][0-9]{1,3}$', XYZ) = 0 THEN XYZ
                                 WHEN PATINDEX('^[0-9]{1,8}$',XYZ) = 0 THEN CAST(XYZ AS decimal(18,3))/1000
                                 ELSE NULL 
                             END
              )
FROM @table

OUTPUT:

---------------------------------------
4000.000
3.123
7.000
80000.000
NULL

(5 row(s) affected)
KM
not working. I guess PATINDEX is not doing what i was expecting it to do
rs
how `not working`, works for all given sample data?
KM
if we are dividing by 1000 , 4000.000 = 4.000?
rs
no it isn't, all rows in the example get processed via the first `WHEN` none by the second `WHEN` and the null row by the `ELSE`. What are you trying to do with the `PATINDEX`?
KM
yes i realized that, check my updated question, I'm trying to match using regex
rs
+1  A: 

Try this..

DECLARE @table table(XYZ VARCHAR(8) , id int)

INSERT INTO @table
SELECT '4000', 1
UNION ALL
SELECT '3.123', 2
UNION ALL
SELECT '7.0', 3
UNION ALL
SELECT '80000', 4
UNION ALL
SELECT NULL, 5
UNION ALL
SELECT 'WTF',6

SELECT CASE 
     WHEN ISNUMERIC(XYZ) = 0 THEN NULL
     WHEN CHARINDEX('.',XYZ,0) < LEN(XYZ)-2 AND CHARINDEX('.',XYZ,0) > 0 THEN XYZ
     WHEN ISNUMERIC(XYZ) >0  then  convert(decimal(18,3),xyz) / 1000.000
     ELSE NULL
END
  FROM @table

Output

4.00000000000
3.12300000000
0.00700000000
80.00000000000
NULL
NULL

Edit - to keep to 3 decimal places in output do this

SELECT convert(decimal(8,3),CASE 
     WHEN ISNUMERIC(XYZ) = 0 THEN NULL
     WHEN CHARINDEX('.',XYZ,0) < LEN(XYZ)-2 AND CHARINDEX('.',XYZ,0) > 0 THEN XYZ
     WHEN ISNUMERIC(XYZ) >0  then  convert(decimal(18,3),xyz) / 1000.000
     ELSE NULL
END)
  FROM @table

Note the (8,3) defines this, total precision 8 digits, 3 after the point.

You may wish to convert back to varchar(8) too

CResults
perfect thanks this is what i was looking for, But why does it pads extra 8 0's at the end?
rs
see my edit. I've kept precision to 8 to suit your original varchar
CResults
yes thanks, I'm confused about what is causing it to pad so many zeros.
rs
A: 
select xyz, ((case when charindex('.', xyz) > 0 then cast(xyz AS decimal(18,3))*1000
                   else cast(xyz AS decimal(18,3)) end))/1000
from #table
HLGEM
not working. it returns same values
rs
Fixed, try it again
HLGEM
you are close but we don't need that * 1000 extra there :)
rs
yeah you do or you end up with 4.000000000.003123000.0070000080.00000000NULL
HLGEM