SQL-запрос для разбора данных одного столбца на несколько столбцов с использованием разделителя

#sql-server #tsql #sql-server-2008-r2

#sql-сервер #tsql #sql-server-2008-r2

Вопрос:

Мне нужен SQL-запрос, который позволит мне разделить один столбец на несколько столбцов. Например: набор данных 1 = «10.11.5-Нет-bobadmin:501 -1-1-87- PASS-11.1.0.9900-true» Будет разделен на отдельные столбцы на основе символа «-«. Набор данных вернет следующее

 Col1    Col2    Col3    Col4    Col5    Col6    Col7    Col8    Col9
10.11.5 None    bobadmin:501    1   1   87  PASS    11.1.0.9900 TRUE
  

Любая помощь приветствуется!

Использование SQL Server 2008R2

Ответ №1:

В приведенном ниже примере у меня есть 9 позиций, но он легко расширяется на столько, сколько вам нужно

 Declare @YourTable table (ID int,DataSet1 varchar(100))
Insert Into @YourTable values
(1,'10.11.5-None-bobadmin:501 -1-1-87-PASS-11.1.0.9900-true'),
(2,'10.11.6-All-JaneAdmin:999 -9-9-99-FAIL-12.2.2.555-false')

Select A.ID
      ,B.*
 From  @YourTable A
 Cross Apply (
                Select Col1 = xDim.value('/x[1]','varchar(max)')
                      ,Col2 = xDim.value('/x[2]','varchar(max)')
                      ,Col3 = xDim.value('/x[3]','varchar(max)')
                      ,Col4 = xDim.value('/x[4]','varchar(max)')
                      ,Col5 = xDim.value('/x[5]','varchar(max)')
                      ,Col6 = xDim.value('/x[6]','varchar(max)')
                      ,Col7 = xDim.value('/x[7]','varchar(max)')
                      ,Col8 = xDim.value('/x[8]','varchar(max)')
                      ,Col9 = xDim.value('/x[9]','varchar(max)')
                 From (Select Cast('<x>'   Replace(A.DataSet1,'-','</x><x>') '</x>' as XML) as xDim) A
             ) B 
  

ВОЗВРАТ

введите описание изображения здесь

Редактировать

Или, если вы хотите UDF

 Select * from [dbo].[udf-Str-Parse-Row]('10.11.5-None-bobadmin:501 -1-1-87-PASS-11.1.0.9900-true','-')
  

ВОЗВРАТ

введите описание изображения здесь

UDF, если необходимо

 CREATE FUNCTION [dbo].[udf-Str-Parse-Row] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (
    Select Pos1 = xDim.value('/x[1]','varchar(max)')
          ,Pos2 = xDim.value('/x[2]','varchar(max)')
          ,Pos3 = xDim.value('/x[3]','varchar(max)')
          ,Pos4 = xDim.value('/x[4]','varchar(max)')
          ,Pos5 = xDim.value('/x[5]','varchar(max)')
          ,Pos6 = xDim.value('/x[6]','varchar(max)')
          ,Pos7 = xDim.value('/x[7]','varchar(max)')
          ,Pos8 = xDim.value('/x[8]','varchar(max)')
          ,Pos9 = xDim.value('/x[9]','varchar(max)')
     From (Select Cast('<x>'   Replace(@String,@Delimiter,'</x><x>') '</x>' as XML) as xDim) A
)
--Select * from [dbo].[udf-Str-Parse-Row]('Dog,Cat,House,Car',',')
  

Комментарии:

1. Большое вам спасибо! Ваше первое решение работает хорошо.

2. Я также протестирую второй, чтобы увидеть, что дает наибольшую производительность. Еще раз спасибо!

3. @user3170410 Первый даст немного лучшую производительность. Второй предназначен только для удобства.