powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Разбить строку на записи через CTE
15 сообщений из 15, страница 1 из 1
Разбить строку на записи через CTE
    #39065396
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
declare @d varchar(max)='11111,22,333,'

;with v(i, period) as (
	select CHARINDEX(',',@d), SUBSTRING(@d, 0, CHARINDEX(',',@d)) 
	union all
	select CHARINDEX(',', @d, i+1),SUBSTRING(@d, i+1, CHARINDEX(',',@d)-1) 
	from v 
	where i>0
)
select * from v where i>0

Если через запятую перечислены строки одинаковой длины, то все в порядке, а если разной, то получается ерунда.
Не могу понять, где я налажал.
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065438
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,

а чем не устраивает по старинке через xml?

Код: sql
1.
2.
3.
4.
5.
declare @d varchar(max), @x xml
set @d='11111,22,333,'

set @x = convert(xml, '<a>' + replace(@d, ',', '</a><a>') + '</a>')
select T.c.value('.', 'varchar(255)') from @x.nodes('/a') T(c) where T.c.exist('text()') = 1
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065460
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тем, что это не единственная строка, а набор записей.

id строка1 11111;22;333;2 345;567;5643;
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065464
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Соответственно на выходе должно быть
idperiod1 111112213332345256725643
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065467
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy,

лучше использовать не CTE, а таблицу целых чисел.
Например: Функция, которая делит строку на слова
В той теме и ещё варианты есть.
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065478
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyСоответственно на выходе должно быть
idperiod1 111112213332345256725643

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
create function xml_tbl (@id int, @value varchar(max), @sep varchar(255))
returns table 
as 
return (
select @id as id, T.c.value('.', 'varchar(255)') as value
from (select convert(xml, '<a>' + replace(@value, @sep, '</a><a>') + '</a>') as val) X
    outer apply X.val.nodes('/a') T(c)
where T.c.exist('text()')=1


)

declare @tbl table (id int, value varchar(max))
insert into @tbl values (1, '11111;22;333;')
insert into @tbl values (2, '345;567;5643;')


select t.id,
       X.value
from @tbl t
    outer apply dbo.xml_tbl(t.id, t.value, ';') X
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065480
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iap,

Чем лучше, шустрее?
И что-то не догоняю, как прикрутить ParseString к select id, str2parse from tbl1
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065482
samoxod
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Antonariy,
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
declare @d varchar(max)='11111,22,333,'

;with v(i, period) as (
	select CHARINDEX(',',@d), SUBSTRING(@d, 0, CHARINDEX(',',@d)) 
	union all
	select CHARINDEX(',', @d, v.i+1), SUBSTRING(@d, v.i+1, ABS(CHARINDEX(',', @d, v.i+1)-v.i)-1 )
	from v 
	where i>0
)
select * from v where i>0
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065485
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff,

Спасибо, но мучают меня сомнения насчет производительности.
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065488
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariyfelix_ff,

Спасибо, но мучают меня сомнения насчет производительности.

где то на форуме, была тема про парсинг строки поищите, там даже invm или churupaha по-моему замеры производил различных методов, xml довольно шустро бегает.

ну если хотите можете поизвращаться с stuff/substring но геммора много.

в любом случае вам для получения необходимого результата будет необходим некий метод дающий результирующую таблицу которую потом вы кроме как apply не примапите
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065492
СТУДЕНТ123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Через табличную функцию, у меня в таком виде хранятся права доступа к вкладкам самописной системы, знаю криво, но переписывать в нормальные вид приложение не особо хочется ((

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
ALTER FUNCTION [dbo].[GETxRULESxUSERS] 
( @LIST	NVARCHAR(4000), @DELIMETER	NCHAR(1) = N','
) RETURNS TABLE AS RETURN	
WITH [LIST] ([NO],[POS],[TO]) AS (
	SELECT	0,0,0
UNION ALL
	SELECT	L.[NO] + 1,L.[TO] + 1,I.[TO]
	FROM	[LIST] L CROSS APPLY (SELECT CHARINDEX(@DELIMETER,@LIST + @DELIMETER,L.[TO] + 1)) I ([TO])
	WHERE	I.[TO] > 0
)	SELECT	[NO],SUBSTRING(@LIST,[POS],[TO]-[POS])	AS ITEM	,[POS]
	FROM	[LIST]
	WHERE	[TO] > [POS]



Теперь результат:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
DECLARE @TABLE TABLE (ID INT, STRS VARCHAR(MAX))

INSERT INTO @TABLE SELECT 1,'11111;22;333;'
INSERT INTO @TABLE SELECT 2,'345;567;5643;'

SELECT * FROM @TABLE

SELECT T.ID, GRU.ITEM
FROM @TABLE AS T CROSS APPLY dbo.GETxRULESxUSERS(T.STRS,';') AS GRU
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065494
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyСпасибо, но мучают меня сомнения насчет производительности. 15097121
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065497
СТУДЕНТ123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ALTER на CREATE сами замените, что то я упустил этот момент
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39065503
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmAntonariyСпасибо, но мучают меня сомнения насчет производительности. 15097121 Внезапно выходит, что вариант с xml самый шустрый, а мой практически самый тормозной :)

Спасибо за науку.
...
Рейтинг: 0 / 0
Разбить строку на записи через CTE
    #39066157
Valer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariy, вариант с CTE
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
;
declare @delim  char(1)
select @delim = ';'
declare @tbl table (id int, value varchar(max))
insert into @tbl values (1, '11111;22;333;')
insert into @tbl values (2, '345;567;5643;')
;
with tdelim   as 
( select 
    t.id
   ,v.number 
from master.dbo.spt_values v 
 , @tbl t
where  substring( t.value , v.number ,1) = @delim
and v.type='P' 
and v.number <= len(t.value) and v.number > 0 
--- + учитываем начало 
union select id, 0 from  @tbl  
),
  tdelim1   as 
( select 
    d.id
   ,d.number  as start
   ,min( d1.number  ) as finish
from tdelim  d
inner join tdelim  d1
  on d1.id =d.id
  and d.number < d1.number
group by     d.id  ,d.number   
 )
select d.id
 ,d.start 
 , d.finish 
 ,substring( t.value , d.start+1  ,  d.finish -  d.start -1  ) as word
from tdelim1 d
  inner join @tbl t
    on t.id =d.id
order by d.id
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Разбить строку на записи через CTE
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]