Как выбрать n-й элемент в поле с разделенными значениями в таблице базы данных SQL? - PullRequest
0 голосов
/ 07 октября 2018

Итак, мы получили поле кода с разделенными значениями, такими как 'a_bb_ccc_dddd' и нужно третье значение, это 'ccc'.

Я на самом деле получаю первое с верхним N.

DECLARE @table1 TABLE (path VARCHAR(MAX));

INSERT INTO @table1 (path) 
VALUES ('a_bb_ccc_dddd'), ('111_222_333_444'), ('')

SELECT
    path, 
    (SELECT TOP 1 value 
     FROM STRING_SPLIT (path, '_')) AS part
FROM
    @table1

Ответы [ 4 ]

0 голосов
/ 07 октября 2018

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

SELECT SUBSTRING(path, LPart + 1, LEN(path) - (LPart+RPart) ) Path
FROM(
SELECT 
    path 
,   LEN(LEFT(path,CHARINDEX('_', path, CHARINDEX('_', path) + 1))) LPart
,   LEN(SUBSTRING(path, CHARINDEX('_', path, CHARINDEX('_', path, CHARINDEX('_', path) + 1) + 1), LEN(path) - CHARINDEX('_', path, CHARINDEX('_', path, CHARINDEX('_', path) + 1) + 1) +1)) RPart 
from @table1
) D 

Вы можете использовать CHARINDEX('_', path), чтобы получить номер позиции первого подчеркивания, а затем вы можете повторить его + 1 дляполучить второе подчеркивание CHARINDEX('_', path, CHARINDEX('_', path) + 1).Затем все, что вам нужно сделать, это просто использовать эти цифры с SUBSTRING().

0 голосов
/ 07 октября 2018

используйте это

create FUNCTION [dbo].[iteration] (@string nvarchar(max), @delimiter nvarchar(50),@iter int)

returns nvarchar(max)
as begin
declare @result nvarchar(300)
SELECT @result = value from --into #COLUMNs
(select value,row_number() over(order by (select null))  [rn]
FROM STRING_SPLIT(@string,'_'))a
where a.rn = @iter


return @result
end
GO

, затем просто выполните запрос:

DECLARE @table1 TABLE (path varchar(max));
declare @iter int 
INSERT INTO @table1 (path) VALUES ('a_bb_ccc_dddd')
INSERT INTO @table1 (path) VALUES ('111_222_333_444')
INSERT INTO @table1 (path) VALUES ('')

select path, dbo.iteration(path,'_',3)
from @table1 a

, если вы хотите изменить его на 2-ю итерацию, измените 3 на 2 и т. Д.

0 голосов
/ 07 октября 2018

Как насчет этого:

SELECT path, value
FROM @table1
OUTER APPLY (
  SELECT value
  FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), value 
    FROM string_split(path, '_')
    ) split (rn, value)
  WHERE rn = 3
) splitval;
0 голосов
/ 07 октября 2018

Это сложно.Вероятно, вы легко найдете в сети функцию split(), которая содержит порядковый номер элемента.

В другом методе используется рекурсивный CTE:

with cte as (
      select stuff(path, 1, len(v.element) + 1, '') as path, v.element, 1 as lev
      from table1 cross apply
           (values (left(path, charindex('_', path + '_') - 1))) v(element)
      union all
      select stuff(cte.path, 1, len(v.element) + 1, ''), left(path, charindex('_', path + '_') - 1) as element, 1 + lev
      from cte cross apply
           (values (left(path, charindex('_', path + '_') - 1))) v(element)
      where path <> ''
     )
select *
from cte
where lev = 3;
...