split alpha and numeric using sql

前端 未结 4 568
夕颜
夕颜 2020-12-09 13:31

I have a table and it has a 3 columns. The first column is the data that contains value(numeric) and unit(percentage and etc..), the second col

相关标签:
4条回答
  • 2020-12-09 13:42

    change @concunit & @unitx Respectively

     DECLARE @concunit varchar(10)='45.5%'
    DECLARE @unitx varchar(10)='%'
    
    BEGIN
    SELECT RTRIM(SUBSTRING( @concunit , 1 , CHARINDEX( @unitx , @concunit
                                                  ) - 1
                    )) AS Number, 
           RTRIM(SUBSTRING( @concunit , CHARINDEX( @unitx , @concunit
                                              ) , LEN( @concunit
                                                     ) - (CHARINDEX( @unitx , @concunit
                                                                   ) - 1)
                    )) AS Unit
    
    end
    
    0 讨论(0)
  • 2020-12-09 13:51

    Would something like this work? Based on the shown data it looks like it would.

    Apply it to your data set as a select and if you like the results then you can make an update from it.

    WITH cte as (SELECT 'ug/mL' ConcUnit, 500 as [Numeric], '' as Unit 
       UNION ALL SELECT '2000 ug/mL',     NULL,             '')
    
    SELECT
        [ConcUnit]                  as [ConcUnit],
        [Numeric]                   as [Original Numeric],
        [Unit]                      as [Original Unit],
        CASE WHEN ConcUnit LIKE '% %' THEN 
            SUBSTRING(ConcUnit, 1, CHARINDEX(' ', ConcUnit) - 1) 
            ELSE [Numeric] END      as [New Numeric],
        CASE WHEN ConcUnit LIKE '% %' 
            THEN SUBSTRING(ConcUnit, CHARINDEX(' ', ConcUnit) + 1, LEN(ConcUnit)) 
            ELSE ConcUnit END       as [New Unit]
    FROM cte
    
    0 讨论(0)
  • 2020-12-09 13:53

    Here is my answer. Check output in SQLFiddle for the same.

    create TABLE temp
    (
          string NVARCHAR(50)
    )
    
    INSERT INTO temp (string)
    VALUES 
        ('4000 ug\ml'),
        ('2000 ug\ml'),
        ('%'),
        ('ug\ml')
    
    SELECT subsrtunit,LEFT(subsrtnumeric, PATINDEX('%[^0-9]%', subsrtnumeric+'t') - 1)
    FROM (
        SELECT subsrtunit = SUBSTRING(string, posofchar, LEN(string)),
      subsrtnumeric = SUBSTRING(string, posofnumber, LEN(string))
        FROM (
            SELECT string, posofchar = PATINDEX('%[^0-9]%', string),
          posofnumber = PATINDEX('%[0-9]%', string)
            FROM temp
        ) d
    ) t
    

    Updated Version to handle 99.5 ug\ml

    create TABLE temp
    (
          string NVARCHAR(50)
    )
    
    INSERT INTO temp (string)
    VALUES 
        ('4000 ug\ml'),
        ('2000 ug\ml'),
        ('%'),
        ('ug\ml'),
        ('99.5 ug\ml')
    
    SELECT subsrtunit,LEFT(subsrtnumeric, PATINDEX('%[^0-9.]%', subsrtnumeric+'t') - 1)
    FROM (
        SELECT subsrtunit = SUBSTRING(string, posofchar, LEN(string)),
      subsrtnumeric = SUBSTRING(string, posofnumber, LEN(string))
        FROM (
            SELECT string, posofchar = PATINDEX('%[^0-9.]%', string),
          posofnumber = PATINDEX('%[0-9.]%', string)
            FROM temp
        ) d
    ) t
    

    Updated Version: To handle 1 000 ug\ml,20 000ug\ml

    create TABLE temp
    (
          string NVARCHAR(50)
    )
    
    INSERT INTO temp (string)
    VALUES 
        ('4000 ug\ml'),
        ('2000 ug\ml'),
        ('%'),
        ('ug\ml'),
        ('99.5 ug\ml'),
        ('1 000 ug\ml'),
        ('20 000ug\ml')
    
    SELECT substring(replace(subsrtunit,' ',''),PATINDEX('%[0-9.]%', replace(subsrtunit,' ',''))+1,len(subsrtunit)),
    LEFT(replace(subsrtnumeric,' ',''), PATINDEX('%[^0-9.]%', replace(subsrtnumeric,' ','')+'t') - 1)
    FROM (
        SELECT subsrtunit = SUBSTRING(string, posofchar, LEN(string)),
      subsrtnumeric = SUBSTRING(string, posofnumber, LEN(string))
        FROM (
            SELECT string, posofchar = PATINDEX('%[^0-9.]%', replace(string,' ','')),
          posofnumber = PATINDEX('%[0-9.]%', replace(string,' ',''))
            FROM temp
        ) d
    ) t
    

    Check out SQLFiddle for the same.

    0 讨论(0)
  • 2020-12-09 14:06

    If the numeric part is always at the beginning, then you can use this:

    PATINDEX('%[0-9][^0-9]%', ConcUnit)
    

    to get the index of the last digit.

    Thus, this:

    DECLARE @str VARCHAR(MAX) = '4000 ug/ML' 
    
    SELECT LEFT(@str, PATINDEX('%[0-9][^0-9]%', @str )) AS Number,
           LTRIM(RIGHT(@str, LEN(@str) - PATINDEX('%[0-9][^0-9]%', @str ))) As Unit
    

    gives you:

    Number  Unit
    -------------
    4000    ug/ML
    

    EDIT:

    If numeric data include double values as well, then you can use this:

    SELECT LEN(@str) - PATINDEX ('%[^0-9][0-9]%', REVERSE(@str))
    

    to get the index of the last digit.

    Thus, this:

    SELECT LEFT(@str, LEN(@str) - PATINDEX ('%[^0-9][0-9]%', REVERSE(@str)))
    

    gives you the numeric part.

    And this:

    SELECT LEFT(@str, LEN(@str) - PATINDEX ('%[^0-9][0-9]%', REVERSE(@str))) AS Numeric,
           CASE 
              WHEN CHARINDEX ('%', @str) <> 0 THEN LTRIM(RIGHT(@str, LEN(@str) - CHARINDEX ('%', @str)))
              ELSE LTRIM(RIGHT(@str, PATINDEX ('%[^0-9][0-9]%', REVERSE(@str))))
           END AS Unit
    

    gives you both numberic and unit part.

    Here are some tests that I made with the data you have posted:

    Input:

    DECLARE @str VARCHAR(MAX) = '50 000ug/ML'
    

    Output:

    Numeric Unit
    ------------
    50 000  ug/ML
    

    Input:

    DECLARE @str VARCHAR(MAX) = '99.5%'
    

    Output:

    Numeric Unit
    ------------
    99.5    
    

    Input:

    DECLARE @str VARCHAR(MAX) = '4000 . 35 % ug/ML'
    

    Output:

    Numeric     Unit
    ------------------
    4000 . 35   ug/ML
    
    0 讨论(0)
提交回复
热议问题