мне нужна подстрока для извлечения данных из поля - PullRequest
0 голосов
/ 06 мая 2019

У меня есть поле, содержащее символ в этом формате 1_US_01_103_157_G014. Символы в поле объединены _, как вы можете видеть в приведенном примере.

Я хотел бы создать Tsql для извлечения каждого символа в свой собственный столбец, например, при условии, что Столбец 1 = 1_US_01_103_157_G014. Производный столбец 2 = 1. Столбец 3 = США, столбец 4 = 01, столбец 5 = 103, столбец 6 = 157, столбец 7 = G014.

Ответы [ 3 ]

1 голос
/ 06 мая 2019

Вы можете заменить подчеркивание _ и преобразовать результат в xml, а затем обработать его. Как то так.

declare @tbl table(col1 varchar(50))
insert @tbl(col1) values ('1_US_01_103_157_G014')

;with cte as(
    select col1, cast('<t><x>'+REPLACE(col1,'_','</x><x>')+'</x></t>' as xml) x
    from @tbl
)
select col1,
    t.v.value('x[1]', 'varchar(20)') col2,
    t.v.value('x[2]', 'varchar(20)') col3,
    t.v.value('x[3]', 'varchar(20)') col4,
    t.v.value('x[4]', 'varchar(20)') col5,
    t.v.value('x[5]', 'varchar(20)') col6,
    t.v.value('x[6]', 'varchar(20)') col7
from cte
cross apply x.nodes('t') t(v)
0 голосов
/ 06 мая 2019

Это легко, используя CROSS APPLY. Обратите внимание, что временная переменная ниже позволяет вам проверить это. В вашей среде вы бы заменили @tbl любой таблицей, с которой работаете.

-- Your table (change the query to point to your real table)
DECLARE @tbl TABLE(col1 VARCHAR(50))
INSERT @tbl(col1) VALUES ('1_US_01_103_157_G014');

SELECT
  C1 = t.col1,
  C2 = SUBSTRING(t.col1,1,d1.D-1), 
  C3 = SUBSTRING(t.col1,d1.D+1,d2.D-d1.D-1),
  C4 = SUBSTRING(t.col1,d2.D+1,d3.D-d2.D-1),
  C5 = SUBSTRING(t.col1,d3.D+1,d4.D-d3.D-1),
  C6 = SUBSTRING(t.col1,d4.D+1,d5.D-d4.D-1),
  C7 = SUBSTRING(t.col1,d5.D+1,8000)
FROM @tbl AS t
CROSS APPLY (VALUES(CHARINDEX('_',t.col1)))        AS d1(D)
CROSS APPLY (VALUES(CHARINDEX('_',t.col1,d1.D+1))) AS d2(D)
CROSS APPLY (VALUES(CHARINDEX('_',t.col1,d2.D+1))) AS d3(D)
CROSS APPLY (VALUES(CHARINDEX('_',t.col1,d3.D+1))) AS d4(D)
CROSS APPLY (VALUES(CHARINDEX('_',t.col1,d4.D+1))) AS d5(D);

Возвращает

C1                     C2  C3   C4   C5   C6    C7
---------------------- --- ---- ---- ---- ----- -------
1_US_01_103_157_G014   1   US   01   103  157   G014
0 голосов
/ 06 мая 2019

Вот подход, который я бы предложил:

Для начала вам понадобится функция split для преобразования строки в таблицу

go
create function [dbo].[Split]
(
    @String nvarchar(4000),
    @Delimiter nchar(1)
)
returns table
as
return
(
    with Split(stpos, endpos)
    as(
        select 0 as stpos, charindex(@Delimiter,@String) AS endpos
        union all
        select endpos+1, charindex(@Delimiter,@String,endpos+1)
            from Split
            where endpos > 0
    )
    select 'Id' = row_number() over (order by (select 1)),
        'Data' = substring(@String,stpos,coalesce(nullif(endpos,0),len(@String)+1)-stpos)
    from Split
)

Так что теперь вы можете сделать это:

go
declare @inputString nvarchar(128) set @inputString = '1_US_01_103_157_G014'
select * from dbo.Split(@inputString, '_')

, который производит таблицу: enter image description here

Второе ... Вы можете использовать оператор поворота для преобразования строки в столбцы

go
declare @inputString nvarchar(128) set @inputString = '1_US_01_103_157_G014'

SELECT 'values', [1], [2], [3], [4], [5], [6]  
FROM  
(select Id, Data from dbo.Split(@inputString, '_')) AS SourceTable  
PIVOT  
(  
max(Data)  
FOR Id IN ([1], [2], [3], [4], [5], [6])  
) AS PivotTable;  

А pivot даст следующий результат:

enter image description here

Из вашего вопроса не совсем ясно, что именно вы пытаетесь сделать, но это хорошая отправная точка.

Надеюсь, это поможет 10

...