Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Альтернативная агрегация строк.  [new]
Jaffar
Member

Откуда:
Сообщений: 633
Добрый день.


Суть вопроса в следующем:
есть запрос примерно следующего вида

[sql]
select t1.ID, tx.Col1, tx.Col2
from table1 t1
cross apply(select dbo.strconcat(t2.Column1 + t2.Column2+char(13)+char(10)) Col1,
dbo.strconcat(t2.Column3 + t2.Column4+char(13)+char(10)) Col2
from Table2 t2
where
t2.TYP = t1.ID) tx [/sql]

где, dbo.strconcat - агрегирующая функция(из allembly) - самописная.
по причине того что данная фкнкция имеет тип входного и выходного пар-ра varchar(8000) - для больших строк она не подходит.
более того эта функция самописная, а хотелось бы при возможности пользоваться штатными средствами.

поэтому было найдено полурешение использовать FOR XML PATH('')
т.е. запрос стал выглядель так:

[sql]
select t1.ID, tx1.Col1, tx2.Col2
from table1 t1
cross apply(select (select t2.Column1 + t2.Column2+char(13)+char(10)
from Table2 t2
where
t2.TYP = t1.ID
FOR XML PATH('')) Col1 ) tx1
cross apply(select (select t2.Column3 + t2.Column4+char(13)+char(10)
from Table2 t2
where
t2.TYP = t1.ID
FOR XML PATH('')) Col2 ) tx2
[/sql]

в итоге получается 2 cross apply, что не очень хорошо,
особенно если в первом запросе будет не 2, а скажем 5 столбцов вида dbo.strconcat(t2.Column_N + t2.Column_M+char(13)+char(10)) ColX,
и таблиц в cross apply будет поболее и/или запрос будет посложнее, получается огромный плохочитаемый и дублирующийся код, не говоря уже о скорости.

Можно ли с помощью FOR XML получить агрегацию из нескольких столбцов в одном запросе, примерно как то так:
[sql]
select t1.ID, tx.Col1, tx.Col2, .... tx.ColN
from table1 t1
cross apply(select t2.Column1 + t2.Column2+char(13)+char(10) Col1,
t2.Column3 + t2.Column4+char(13)+char(10) Col2,
--.........
t2.ColumnN + t2.ColumnM+char(13)+char(10) ColN,
from Table2 t2
where
t2.TYP = t1.ID
FOR XML /*.......*/) Col1 ) tx
[/sql]
Или так сделать нельзя?
Хотелось бы иметь на этот случай штатный механизм.
Начал копать в сторону FOR XML PATH('') - может кто-то сталкивался с этим, потому как я пока не нашел там такой возможности?
Или может быть что-то еще.

PS: писать для каждого случая функцию в которой агрегировать рукми, типа select @STR = @STR + ....
или использовать курсоры или циклы не предлагать....
6 мар 13, 10:13    [14017984]     Ответить | Цитировать Сообщить модератору
 Re: Альтернативная агрегация строк.  [new]
Jaffar
Member

Откуда:
Сообщений: 633
Добрый день.


Суть вопроса в следующем:
есть запрос примерно следующего вида

select t1.ID, tx.Col1, tx.Col2
from table1 t1
cross apply(select dbo.strconcat(t2.Column1 + t2.Column2+char(13)+char(10)) Col1,
				   dbo.strconcat(t2.Column3 + t2.Column4+char(13)+char(10)) Col2
			from Table2 t2
			where
					t2.TYP = t1.ID) tx 


где, dbo.strconcat - агрегирующая функция(из allembly) - самописная.
по причине того что данная фкнкция имеет тип входного и выходного пар-ра varchar(8000) - для больших строк она не подходит.
более того эта функция самописная, а хотелось бы при возможности пользоваться штатными средствами.

поэтому было найдено полурешение использовать FOR XML PATH('')
т.е. запрос стал выглядель так:

select t1.ID, tx1.Col1, tx2.Col2
from table1 t1
cross apply(select (select t2.Column1 + t2.Column2+char(13)+char(10) 
			from Table2 t2
			where
					t2.TYP = t1.ID
			FOR XML PATH('')) Col1 ) tx1
cross apply(select (select t2.Column3 + t2.Column4+char(13)+char(10) 
			from Table2 t2
			where
					t2.TYP = t1.ID
			FOR XML PATH('')) Col2 ) tx2


в итоге получается 2 cross apply, что не очень хорошо,
особенно если в первом запросе будет не 2, а скажем 5 столбцов вида dbo.strconcat(t2.Column_N + t2.Column_M+char(13)+char(10)) ColX,
и таблиц в cross apply будет поболее и/или запрос будет посложнее, получается огромный плохочитаемый и дублирующийся код, не говоря уже о скорости.

Можно ли с помощью FOR XML получить агрегацию из нескольких столбцов в одном запросе, примерно как то так:
select t1.ID, tx.Col1, tx.Col2, .... tx.ColN
from table1 t1
cross apply(select  t2.Column1 + t2.Column2+char(13)+char(10) Col1,
					t2.Column3 + t2.Column4+char(13)+char(10) Col2,
					 --.........
					 t2.ColumnN + t2.ColumnM+char(13)+char(10) ColN,
			from Table2 t2
			where
					t2.TYP = t1.ID
			FOR XML /*.......*/) Col1 ) tx

Или так сделать нельзя?
Хотелось бы иметь на этот случай штатный механизм.
Начал копать в сторону FOR XML PATH('') - может кто-то сталкивался с этим, потому как я пока не нашел там такой возможности?
Или может быть что-то еще.

PS: писать для каждого случая функцию в которой агрегировать рукми, типа select @STR = @STR + ....
или использовать курсоры или циклы не предлагать....
6 мар 13, 10:15    [14017995]     Ответить | Цитировать Сообщить модератору
 Re: Альтернативная агрегация строк.  [new]
invm
Member

Откуда: Москва
Сообщений: 9723
select t1.ID,
 tx.x.query('for $v in /Col1 return data($v)').value('.', 'varchar(max)'),
 ...
 tx.x.query('for $v in /ColN return data($v)').value('.', 'varchar(max)')
from table1 t1
cross apply(select  t2.Column1 + t2.Column2+char(13)+char(10) Col1,
					t2.Column3 + t2.Column4+char(13)+char(10) Col2,
					 --.........
					 t2.ColumnN + t2.ColumnM+char(13)+char(10) ColN,
			from Table2 t2
			where
					t2.TYP = t1.ID
			FOR XML path(''), type)) tx(x);
6 мар 13, 11:06    [14018292]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить