SQL Server 2005: как разбить столбец с неизвестным количеством разбиений - PullRequest
1 голос
/ 22 июня 2011

У меня больше проблем с разбиением столбцов в стеке, и я хотел бы помочь с завершением этой последней части. Я пытался применить другое решение, которое у меня было, но безуспешно.

Таблица БД:

ID INT,
SN varchar(100),
Types varchar(1000)

Пример:

ID     SN    Types
1      123   ABC,XYZ,TEST
2      234   RJK,CDF,TTT,UMB,UVX
3      345   OID,XYZ

Желаемый вывод:

* * 1010

Ответы [ 3 ]

2 голосов
/ 23 июня 2011

вот здесь я должен разбить строку с разделителями

declare @table table (ID int identity(1,1), String varchar(max))
declare @delim varchar(max)

insert into @table values ('abc,def')
insert into @table values ('ghij,klmn,opqrst')

set @delim=','


;with c as
(
    select 
        ID, 
        --String,
        CHARINDEX(@delim,String,1) as Pos,
        case when CHARINDEX(@delim,String,1)>0 then SUBSTRING(String,1,CHARINDEX(@delim,String,1)-1) else String end as value,
        case when CHARINDEX(@delim,String,1)>0 then SUBSTRING(String,CHARINDEX(@delim,String,1)+1,LEN(String)-CHARINDEX(@delim,String,1)) else '' end as String
    from @table

    union all
    select
        ID,
        CHARINDEX(@delim,String,1) as Pos,
        case when CHARINDEX(@delim,String,1)>0 then SUBSTRING(String,1,CHARINDEX(@delim,String,1)-1) else String end as Value,
        case when CHARINDEX(@delim,String,1)>0 then SUBSTRING(String,CHARINDEX(@delim,String,1)+1,LEN(String)-CHARINDEX(@delim,String,1)) else '' end as String
    from c
    where LEN(String)>0
)

select ID, Value from c
2 голосов
/ 23 июня 2011
declare @T table(ID int, SN varchar(100), Types varchar(1000))

insert into @T
select 1, 123, 'ABC,XYZ,TEST' union all
select 2, 234, 'RJK,CDF,TTT,UMB,UVX' union all
select 4, 234, 'XXX' union all
select 3, 345, 'OID,XYZ'

;with cte(ID, SN, Types, Rest) as
(
  select ID,
         SN,
         cast(substring(Types+',', 1, charindex(',', Types+',')-1) as varchar(100)),
         stuff(Types, 1, charindex(',', Types), '')+','
  from @T
  where len(Types) > 0
  union all
  select ID,
         SN,
         cast(substring(Rest, 1, charindex(',', Rest)-1) as varchar(100)),
         stuff(Rest, 1, charindex(',', Rest), '')
  from cte
  where len(Rest) > 0
)
select ID, SN, Types
from cte
order by ID

Я использую рекурсивный CTE для разбиения строки. Третий столбец Types заполняется первым словом в столбце Типы @T. Stuff удалит первое слово и заполнит столбец Rest, который будет содержать все, кроме первого слова. После UNION ALL это рекурсивная часть, которая в основном делает то же самое, но использует CTE в качестве источника и использует столбец rest для выбора первого слова. Первое слово в столбце rest удаляется с помощью stuff, а затем ..... ну, это рекурсивно, поэтому я остановлюсь здесь на пояснениях Рекурсивная часть заканчивается, когда больше не осталось слов where len(Rest) > 0.

0 голосов
/ 23 июня 2011

Насколько я могу судить, вам нужно будет использовать курсор и оператор while ... Некоторые из этих индексов могут быть отключены по одному, но я думаю, что это вас туда доставит ...

DECLARE MY_CURSOR Cursor 
FOR
SELECT ID, SN, Types
FROM Tbl1
Open My_Cursor 
DECLARE @ID int, @SN varchar(100), @types varchar(1000)
Fetch NEXT FROM MY_Cursor INTO @ID, @SN, @types
While (@@FETCH_STATUS <> -1)
BEGIN
  DECLARE @Pos int
  WHILE @Pos < LEN(@types)
  BEGIN
    DECLARE @type varchar(25)
    DECLARE @nextpos int
    set @nextpos = CHARINDEX(@types, ',', @pos)
    SET @type = SUBSTRING(@types, @pos, @nextpos-@pos)
    INSERT INTO tbl2 (ID, SN, type) VALUES (@ID, @SN, @Type)
    SET @Pos = @nextpos+1
  END


FETCH NEXT FROMMY_CURSOR INTO @VAR1Number, @VAR2DateTime ,@VarLongText 
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
...