如何将Varchar列转换为数字

时间:2016-07-13 10:04:34

标签: sql sql-server

我需要将varchar列数据移动到Numeric但有两个条件。

  1. 所有字母数字值都应迁移为null
  2. 所有小数值都应该保持不变。
  3. 我将条件写为WHERE data like '%[^0-9]%',它对除小数以外的所有记录都正常工作。

    我也有像.001 abcd这样的值,必须传递为null。

    总结一下我需要:

    1) 1234 as 1234
    2) 1.23 as 1.23
    3) ABC as null
    4) .ABC as null
    

6 个答案:

答案 0 :(得分:2)

SQL Server中有默认功能 ISNUMERIC()所以,首先通过该功能检查您的数据值,

Select ISNUMERIC(DATA)

整个查询编写如下,

SELECT CASE WHEN ISNUMERIC(data)=1 THEN CAST(data as decimal(18,2))
            ELSE NULL END as tData FROM DataTable 

根据您的问题,首先我们必须使用数字进行转换,使用 case ,这将满足您的第一个条件,如果值为String则转换为NULL。在上面查询中,条件都已经过了。

编辑:如果您使用的是 SQL SERVER 2012 或更高版本,请使用  TRY_PARSE(),那么也无需担心使用CASE ......

我试过了,

SELECT TRY_PARSE('63.36' as decimal(18,2)) got result 63.36

SELECT TRY_PARSE('.' as decimal(18,2)) got result NULL

答案 1 :(得分:2)

我认为这符合您的规范。它非常冗长,但希望它足以打破条件,明确地做出正确的事情,或者,如果不是,那么它很容易修改:

declare @t table (data varchar(30))

insert into @t(data) values
('1234'),
('1.23'),
('abc'),
('.abc'),
('+6000'),
('1.2.3')

select
    CASE WHEN
        Possible = 1 AND
            (DecCheck = 0 OR
            SingleDec = 1
        ) THEN
            CONVERT(decimal(12,3),data)
        END
from
    @t t
        cross apply
            (select
                --Only contains the correct characters
                CASE WHEN not t.data like '%[^0-9.]%' THEN 1 ELSE 0 END as Possible,
                --Contains a decimal point? (Needs more checks)
                CASE WHEN CHARINDEX('.',t.data) > 0 THEN 1 ELSE 0 END as DecCheck,
                CHARINDEX('.',t.data) as FirstDec --Where the first decimal point is
            ) p
        cross apply
            (select
                CASE WHEN DecCheck = 1 THEN
                    --Only contains one decimal point
                    CASE WHEN LEN(data) = FirstDec + CHARINDEX('.',REVERSE(data)) - 1
                        THEN 1
                    ELSE 0 END
                ELSE 0 END as SingleDec
            ) d

结果:

data                           
------------------------------ ---------------------------------------
1234                           1234.000
1.23                           1.230
abc                            NULL
.abc                           NULL
+6000                          NULL
1.2.3                          NULL

即。您可能想要使用的另一项检查是十进制不能是字符串中的第一个或最后一个字符。通过将这些额外的检查添加到CASE列的第一个SingleDec,这很容易实现。

答案 2 :(得分:0)

尝试ISNUMERIC功能,

SELECT ISNUMERIC('abc')
SELECT ISNUMERIC('1.23')

答案 3 :(得分:0)

在SQL Server上(版本2012,11.0.5343)

SELECT
    CASE WHEN ISNUMERIC('.') = 1 THEN <Field> ELSE 0 END
FROM
    <Table>

工作得很好......

答案 4 :(得分:0)

Thre是A blog post

尝试以下

SELECT 
    CASE 
        WHEN 
            ISNUMERIC(data + 'e0') = 1 THEN CAST(data AS decimal(18,2))
        ELSE NULL END AS tData 
FROM 
    DataTable 

答案 5 :(得分:0)

尝试ISNUMERIC功能

DECLARE @MyTable TABLE(Val VARCHAR(100))

INSERT INTO @MyTable
VALUES
     ('1234')
    ,('1.23')
    ,('ABC')
    ,('.ABC')
    ,('MJA')


Select  Val as OldValue,
        Case
        When ISNUMERIC(Val) = 1
        then Cast(Val as numeric(18,2))
        else null
        end NewValue
From    @MyTable

输出

  OldValue                                  NewValue
-----------------------------------------------------
  1234                                      1234.00
  1.23                                      1.23
  ABC                                       NULL
  .ABC                                      NULL
  MJA                                       NULL

  (5 row(s) affected)