[sql (mssql 2008)] Конкатенация строк как аггрегирующая функция

Alena_08_11

Хочется чего то типа

SrcTable :
id | StrValue
----------------------------
1 | One
1 | Two
2 | Three
2 | Four

select
t.id
, MAGIC_CONCAT_FUNCTION(t.StrValue, '@') as Value
from
Table t
group by
t.id

И на выходе

id | Value
--------------------
1 | Two
2 | Four


Бывает ли такое в ms sql 2008 ? Как бы похитрее такое реализовать, если нет ничо готового ?

6yrop

агрегирующие функции можно писать на .NET и загружать в SQL Server

Alena_08_11

Да, спасибо, я тоже слегка поботал эту тему
пока что выеду на

select
t.*
into
#tmp01
from
(
select
1 as ID
, 'One' as StrVal union all
select
1 as ID
, 'Two' as StrVal union all
select
2 as ID
, 'Three' as StrVal union all
select
2 as ID
, 'Four' as StrVal
) t
------------
select distinct
t1.ID
, stuff
select
'@' + t2.StrVal as [text]
from
#tmp01 t2
where
t1.ID = t2.ID
for xml
path ('')
1, 1, '') as Value


from
#tmp01 t1
--------------
drop table #tmp01

Ну а потом мб и до CLR руки дойдут (тут главный вопрос - добиться разрешение на внедрение своих udf clr функций)

hprt

Шурик, к слову про apply и подзапросы в списке полей из соседней темы. Вот запрос автора, переписанный с помощью apply. С точки зрения плана - идентичный

select distinct
t1.ID
, value = stuff(conc.txt, 1, 1, '')
from
#tmp01 t1
cross apply (
select
[data] = '@' + t2.strVal
from
#tmp01 t2
where 1 = 1
and t2.ID = t1.ID
for xml path('')
) conc(txt)

6yrop

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

hprt

да. мало?

Alena_08_11

Спасибо, я тоже заценил cross apply

hprt

небольшое уточнение: это просто apply, т.к. есть cross и outer

Alena_08_11

да да, я про это тоже прочитал, спасибо

6yrop

да. мало?
С точки зрения CQ это улучшение смотрится банально, поскольку там можно выделять любой кусок sql-я:
 
SELECT DISTINCT
t1.ID,
Conc 1, 1, '') as Value
FROM #tmp01 t1

@helper Conc {
<text>
SELECT '@' + t2.StrVal AS [text]
FROM #tmp01 t2
WHERE t1.ID = t2.ID
FROM XML path ('')
</text>
}

Основная ценность apply, когда вытаскивается не одно поле (как ты писал).

6yrop

да. мало?
Кстати, поведение разное. Если подзапрос вдруг возвращает несколько строк, то первый вариант выдаст ошибку, а apply размножит строки.

hprt

Конкретно в этом случае поведение будет идентичное. Подзапрос с for xml "вдруг" не вернет несколько строк. Если ты хочешь поговорить про другие случаи, то ты уверен, что мне нужно объяснять, как работает apply? Кстати, основная ценность apply далеко не в том, что можно вернуть несколько полей. Насчет твоего примера с CQ - просьба не вставлять свое поделие везде, где есть косвенная возможность. Я тебя уверяю, мне твой CQ не понадобится никогда. Я не берусь обсуждать, насколько это круто с точки зрения ООП - у меня нет компетенции, но судя по реакции на форуме, восторгов никто не разделяет. С точки зрения БД - мне на твой фреймворк глубоко пофиг, но твой адский пиар немного достал

6yrop

Что-то ты перевозбудился насчет CQ. :grin: Ведать за живое задел, это хорошо. Раз пошли только эмоции, я так понимаю, к записи запроса претензий нет. Я рад, что у тебя нет возражений по существу. :)

hprt

Какие к черту эмоции? Когда три раза пост удаляешь, прежде чем оставить?) Хотел на второй ответить - не успел :) Я тебе привел пример, как в сиквеле можно использовать apply, ты пишешь, что твой CQ круче, даже не понимая, что такое apply (иначе ты бы не спрашивал "а чем?" в удаленном посте)

6yrop

я посмотрел в гугле http://stackoverflow.com/a/1139231/2724979
Оставить комментарий
Имя или ник:
Комментарий: