2014-11-19 6 views
3

У меня есть таблица и она имеет 3 столбца. first column это данные, которые содержат значение (числовое) и блок (в процентах и ​​т.д ..), второй столбец numeric column, третий Unit column. То, что я хочу сделать, это разделить числовые и единицы из первого столбца, а затем поместить эти данные с разделителями в указанный столбец.split alpha и numeric с использованием sql

Вот мой стол:

UPDATED Image

Я попробовал эту функцию: SO link here..., это действительно расщепление альфа и числовой но я новичок в использовании SQL-функции, моя проблема есть параметр должен быть в строке STRING, так что я сделал, это изменить его на Sub Query, но он дает мне ошибку.

образец кода:

SQL ФУНКЦИЯ:

create function [dbo].[GetNumbersFromText](@String varchar(2000)) 
returns table as return 
(
    with C as 
    (
    select cast(substring(S.Value, S1.Pos, S2.L) as int) as Number, 
      stuff(s.Value, 1, S1.Pos + S2.L, '') as Value 
    from (select @String+' ') as S(Value) 
     cross apply (select patindex('%[0-9]%', S.Value)) as S1(Pos) 
     cross apply (select patindex('%[^0-9]%', stuff(S.Value, 1, S1.Pos, ''))) as S2(L) 
    union all 
    select cast(substring(S.Value, S1.Pos, S2.L) as int), 
      stuff(S.Value, 1, S1.Pos + S2.L, '') 
    from C as S 
     cross apply (select patindex('%[0-9]%', S.Value)) as S1(Pos) 
     cross apply (select patindex('%[^0-9]%', stuff(S.Value, 1, S1.Pos, ''))) as S2(L) 
    where patindex('%[0-9]%', S.Value) > 0 
) 
    select Number 
    from C 
) 

оператора SELECT с подзапросом:

declare @S varchar(max) 
select number from GetNumbersFromText(Select SomeColm From Table_Name) option (maxrecursion 0) 

BTW, им с помощью SQL Server 2005.

Спасибо!

+0

Строка перед первым пространством - это ваше второе значение столбца, строка после пробела - это значение вашего устройства. USE charindex и функция подстроки. – knkarthick24

+0

@ knkarthick24 его не ограничивается «пробелом», некоторые данные - это только одна строка. Например «процент» – Waelhi

+0

Проверьте мою попытку. – knkarthick24

ответ

6

Если числовая часть всегда в начале, то вы можете использовать это:

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

, чтобы получить индекс последней цифры.

Таким образом, это:

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 

дает:

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

EDIT:

Если числовые данные включают в себя двойные значения, а также, то вы можете использовать это:

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

, чтобы получить индекс последней цифры.

Таким образом, это:

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

дает числовую часть.

И это:

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 

дает вам как Numberic и единичную часть.

Вот некоторые тесты, которые я сделал с вами данными публикуемыми:

Вход:

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

Выход:

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

Вход:

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

Выходного :

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

Вход:

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

Выход:

Numeric  Unit 
------------------ 
4000 . 35 ug/ML 
+0

Я пытался .. он работает с некоторым значением, но не с' dot' следующим образом: 'DECLARE @str VARCHAR (MAX) = '45 .5% '' – Waelhi

+0

'.5% 'находится в колонке' UNIT'. – Waelhi

+0

@ Unknownymous2 Извините, я думал, что числовые значения всегда целые числа –

1

Будет что-то вроде этой работы? Основываясь на показанных данных, похоже, что это будет.

Применить его к вашему набору данных как по выбору, и если вам нравятся результаты, вы можете сделать обновление от него.

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

не имеет разделителя 'space', другое значение не имеет' spacing' like 'percent': ' WITH cte as (SELECT 'ug/mL' ConcUnit, 500 as [Числовое], '' как единица UNION ALL SELECT '2000%', NULL, '') ' – Waelhi

1

изменение @concunit & @unitx Соответственно

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

im используя другой unit сэр .. подобный процент – Waelhi

+0

проверьте сейчас пожалуйста –

+0

не работает на 'процент' sir. это дает мне ошибку: «Msg 537, уровень 16, состояние 2, строка 5 Неверный параметр длины передан функции LEFT или SUBSTRING.« – Waelhi

2

Вот мой ответ. Проверьте вывод в SQLFiddle за то же самое.

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 

обновления версии для обработки 99,5 мкг \ мл

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 

обновления версии: Для обработки -000 мкг \ мл, 20 000ug \ мл

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 

Отъезда SQLFiddle для этого же.

+0

его не работает с номером 'double' следующим образом:' 45.5% ''. .5% 'находится на' subsrtunit 'Колонка. – Waelhi

+0

, а также с 4-значным номером с 'spacing' like:' 1 000' – Waelhi

+0

Посмотрите ответ сейчас для обработки ** 99.5 ug \ ml ** – knkarthick24

Смежные вопросы