Разбить строковые значения с пробелами различной длины в три столбца - PullRequest
0 голосов
/ 11 февраля 2020

Моя таблица A col1 имеет три значения и разделена различной длиной. Мне нужно разделить его на три колонки и поместить в Z1, Z2 и Z3 соответственно. Кроме того, в некоторых отдельных значениях между ними тоже есть пробелы, например «Windows XP Professional», но мне нужно, чтобы оно было индивидуальным. Любые идеи? См. Образец ниже. Спасибо.

Текущий

Col                                                                            Z1       Z2     Z3
--------------------------------------------------------------------------   -----    -----   ----  

Windows XP Professional     SP3                       CD RWT-00543
Windows XP                    N/A                          N/A
Windows CE .NET             v5.00               CD TRE-00298 in vault
Client Ctrl firmware      N/A

После

Col                                          Z1                   Z2              Z3
------------------------------------     -------------          -----           ----
                                      Windows XP Professional     SP3        PP RWT-00543
                                         Windows XP               N/A             N/A
                                       Windows CE .NET           v5.00       QQ TRE-00298 in vault
                                        Client Ctrl firmware      N/A

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

STRING_SPLIT не заботится о порядковом положении, поэтому здесь не помогает. Я предлагаю захватить копию DelimitedSplit8K_LEAD. Затем вы можете разделить, как показано ниже:

WITH Splits AS(
    SELECT V.YourColumn,
           DS.ItemNumber,
           DS.Item,
           ROW_NUMBER() OVER (PARTITION BY V.YourColumn ORDER BY DS.ItemNumber) AS RN
    FROM (VALUES ('Windows XP Professional     SP3                       CD RWT-00543'),
                 ('Windows XP                    N/A                          N/A'),
                 ('Windows CE .NET             v5.00               CD TRE-00298 in vault'),
                 ('Client Ctrl firmware      N/A')) V (YourColumn)
         CROSS APPLY dbo.DelimitedSplit8K_LEAD(REPLACE(V.YourColumn, '  ', '|'), '|') DS
    WHERE DS.Item NOT IN ('',' '))
SELECT MAX(CASE S.RN WHEN 1 THEN TRIM(S.Item)END) AS Z1,
       MAX(CASE S.RN WHEN 2 THEN TRIM(S.Item)END) AS Z2,
       MAX(CASE S.RN WHEN 3 THEN TRIM(S.Item)END) AS Z3
FROM Splits S
GROUP BY S.YourColumn;
GO

Если TRIM не найдена функция, используйте LTRIM и RTRIM.

1 голос
/ 11 февраля 2020

Предполагая, что между каждым "столбцом" есть как минимум ДВА пробела.

При перекрестном применении B будет создана "чистая" строка с разделителями трубы ( Спасибо, Гордон! )

Cross Apply C проанализирует новую строку с разделителем трубы в 3 столбца

Пример

Declare @YourTable Table ([Col] varchar(500))
Insert Into @YourTable Values 
 ('Windows XP Professional     SP3                       CD RWT-00543')
,('Windows XP                    N/A                          N/A')
,('Windows CE .NET             v5.00               CD TRE-00298 in vault')
,('Client Ctrl firmware      N/A')

Select C.* 
 From  @YourTable A
 Cross Apply ( values ( ltrim(rtrim(replace(replace(replace([Col],'  ','†‡'),'‡†',''),'†‡','|'))) ) ) B(CleanString)
 Cross Apply (
                Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)')))
                      ,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
                      ,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
                From  ( values (cast('<x>' + replace((Select replace(CleanString,'|','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml)))  A(xDim)
             ) C

Возвращает

Pos1                    Pos2    Pos3
Windows XP Professional SP3     CD RWT-00543
Windows XP              N/A     N/A
Windows CE .NET         v5.00   CD TRE-00298 in vault
Client Ctrl firmware    N/A     NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...