Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Разбить строку на записи через CTE / 15 сообщений из 15, страница 1 из 1
30.09.2015, 16:37
    #39065396
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
Код: 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
30.09.2015, 17:03
    #39065438
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
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
30.09.2015, 17:18
    #39065460
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
Тем, что это не единственная строка, а набор записей.

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

лучше использовать не CTE, а таблицу целых чисел.
Например: Функция, которая делит строку на слова
В той теме и ещё варианты есть.
...
Рейтинг: 0 / 0
30.09.2015, 17:30
    #39065478
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
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
30.09.2015, 17:31
    #39065480
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
iap,

Чем лучше, шустрее?
И что-то не догоняю, как прикрутить ParseString к select id, str2parse from tbl1
...
Рейтинг: 0 / 0
30.09.2015, 17:34
    #39065482
samoxod
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
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
30.09.2015, 17:35
    #39065485
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
felix_ff,

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

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

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

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

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

Код: 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
30.09.2015, 17:41
    #39065494
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
AntonariyСпасибо, но мучают меня сомнения насчет производительности. 15097121
...
Рейтинг: 0 / 0
30.09.2015, 17:42
    #39065497
СТУДЕНТ123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
ALTER на CREATE сами замените, что то я упустил этот момент
...
Рейтинг: 0 / 0
30.09.2015, 17:52
    #39065503
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
invmAntonariyСпасибо, но мучают меня сомнения насчет производительности. 15097121 Внезапно выходит, что вариант с xml самый шустрый, а мой практически самый тормозной :)

Спасибо за науку.
...
Рейтинг: 0 / 0
01.10.2015, 14:06
    #39066157
Valer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на записи через CTE
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
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Разбить строку на записи через CTE / 15 сообщений из 15, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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