Разделить строку при каждом появлении разделителя - PullRequest
0 голосов
/ 28 апреля 2020

Мне нужно разбить эту строку на несколько полей при появлении каждого разделителя, как показано ниже:

Display Value
466500-GO-INF-ITAPPS-EMP-CLERADM

Main Account  Business Unit   Department Cost Center   Asset Type   Classification
466500        GO              INF        ITAPPS        EMP          CLERADM

В настоящее время я использую запрос ниже, чтобы удалить символы перед "-":

stuff([DISPLAYVALUE], 1, charindex('-', [DISPLAYVALUE]), '')

Затем я выполняю этот запрос, чтобы вернуть символы перед «-»:

case

when charindex('-',[DISPLAYVALUE])>0

then Substring([DISPLAYVALUE], 1, Charindex('-', [DISPLAYVALUE])-1)

else [DISPLAYVALUE]

end

К сожалению, это приводит к появлению нескольких вспомогательных столбцов. Есть ли способ достичь этого решения в одном запросе?

1 Ответ

1 голос
/ 02 мая 2020

Вы можете получить желаемый результат, преобразовав вашу строку в XML, а затем воспользовавшись такими методами типа XML, как VALUE (подробнее здесь ), чтобы извлечь необходимую информацию:

DECLARE @mockup TABLE ([DISPLAYVALUE] VARCHAR(100));

INSERT INTO @mockup
VALUES ('466500-GO-INF-ITAPPS-EMP-CLERADM')

;WITH Splitted
AS (
    SELECT  
         CAST('<x>' + REPLACE([DISPLAYVALUE], '-', '</x><x>') + '</x>' AS XML) AS Parts
    FROM @mockup
    )
SELECT
     Parts.value(N'/x[1]', 'int')         as [Main Account]
    ,Parts.value(N'/x[2]', 'varchar(50)') as [Business Unit]
    ,Parts.value(N'/x[3]', 'varchar(50)') as [Department]
    ,Parts.value(N'/x[4]', 'varchar(50)') as [Cost Center]
    ,Parts.value(N'/x[5]', 'varchar(50)') as [Asset Type]
    ,Parts.value(N'/x[6]', 'varchar(50)') as [Classification]
FROM Splitted;

Результат:

Result grid

Первый оператор выбора:

SELECT  
     CAST('<x>' + REPLACE([DISPLAYVALUE], '-', '</x><x>') + '</x>' AS XML) AS Parts
FROM @mockup

преобразует вашу строку в XML документ с последовательностью XML тегов (названных <x>, но вы могли бы использовать здесь что-нибудь еще), каждый из которых содержит одно из ваших значений:

<x>466500</x>
<x>GO</x>
<x>INF</x>
<x>ITAPPS</x>
<x>EMP</x>
<x>CLERADM</x>

Теперь во втором В операторе select вы можете использовать операторы типа c XML, такие как VALUE(), чтобы получить каждое значение из XML и поместить его в отдельный столбец:

SELECT
     Parts.value(N'/x[1]', 'int')         as [Main Account]
    ,Parts.value(N'/x[2]', 'varchar(50)') as [Business Unit]
    ,Parts.value(N'/x[3]', 'varchar(50)') as [Department]
    ,Parts.value(N'/x[4]', 'varchar(50)') as [Cost Center]
    ,Parts.value(N'/x[5]', 'varchar(50)') as [Asset Type]
    ,Parts.value(N'/x[6]', 'varchar(50)') as [Classification]
FROM Splitted;

здесь вы используете XQuery для извлечения одного значения из документа XML, созданного при первом выборе.

Например, для извлечения содержимого первого тега <x> вы используете XQuery '/x[1]' для извлечения первого элемента, '/x[2]' для второго и т. Д.

...