Предыдущий вопрос про comma delimited наоборот

Andriy Loginov
Дата: 17.08.2003 10:46:20
Есть запрсос(SELECT) результат которого выглядит так
field1|field2
aa |b
aa |c
aa |d
bb |b
bb |c
bb |d
А хочется получать на выходе такое
aa |b,c,d
bb |b,c,d
Не подскажет кто как сделать эелательно стандартными функциями

Спасибо
Konrad
Дата: 18.08.2003 07:46:50
Описание таблицы желательно..
Andriy Loginov
Дата: 20.08.2003 18:12:26
Вот сверху же и привел
два поля Что еще нужно?
LeXa NalBat
Дата: 22.08.2003 12:39:35
create function my_cat(char,char) returns char as '
select
case when $1=\'\' or $1 is null
then
case when $2=\'\' or $2 is null
then
\'\'
else
$2
end
else
case when $2=\'\' or $2 is null
then
$1
else
$1 || \', \' || $2
end
end
' language SQL;

create aggregate my_cat( sfunc = my_cat, basetype = char, stype = char, initcond = '' );

select field1, my_cat( field2 ) from table1 group by field1;
assa
Дата: 22.08.2003 19:28:23
Интересно. Встречался вопрос о конкатенации строк при группировке. Надо полагать и такая вещь реализуема?
LeXa NalBat
Дата: 26.08.2003 09:53:56
Код который я привел - это и есть конкатенация строк при группировке, но с разделителем - запятой. Конкатенация без разделителя выглядит намного проще (код не проверял):

create function my_cat(char,char) returns char as 'select $1 || $2' language SQL;

create aggregate my_cat( sfunc = my_cat, basetype = char, stype = char, initcond = '' );

select field1, my_cat( field2 ) from table1 group by field1;
assa
Дата: 27.08.2003 16:46:27
Спасибо за ответ. Я что-то стал рассеян :). Заметил что (пере)спросил собственно об ответе именно на этот вопрос. Пообчитал букварь на эту тему.

Появилось 2 вопроса (~1,5):

1. Правильно ли я понимаю, что агрегатные функции - всегда функции одного переменного (а именно - поля), т.е. нет способа объявления агрегатной функции с некоторым параметром?

Например: Я обобщаю мои желания что-то конкатенировать следующим образом:
CREATE FUNCTION my_cat(char,char, char) RETURNS CHAR AS ' 

SELECT
CASE WHEN $1 = \'
\' or $1 IS NULL THEN
CASE WHEN $2=\'
\' OR $2 IS NULL THEN
\'
\'
ELSE
$2
END
ELSE
CASE WHEN $2=\'
\' OR $2 IS NULL THEN
$1
ELSE
$1 || $3 || $2
END
END
'
LANGUAGE SQL;

где $3 - собственно разделитель. ('' - для простой конкатенации, ', ' - для конкатенации с запятой и т.п.

теперь, предположим, я хотел бы иметь обобщенную агрегатную функцию, некая (первая) переменная которой была бы переменной, по которой ведется агрегирование, а некая иная (вторая) - параметром способа агрегирования. (в нашем случае - разделитель). НАсколько я сейчас понимаю, для реализации такого вызова я должен объявить "обычную" ф-цию 2-х переменных (подставив явное значение параметра), затем объявить агрегатную функцию. Возможность делать это из кода (реализовать процедуру, которая по значению параметра будет генерировать названные ф-ии из "обобщенной") несколько упрощает ситуацию, но все равно, вызов агрегатной возможен только после ее объявления... Насколько правильно мое видение этой ситуации?

2. Есть ли возможность объявить агрегатную функцию по нескольким полям? (положим, вопрос о применении метода свертки по полю 1 должен приниматься из соотношения значения поля 2 и значения свертки поля 2 до текущей, т.е. воспользоваться независимыми агрегатами для неких комбинаций полей не удается). //?Правда, результат, похоже, зависит от порядка обработки записей, но ничего не мешает написать "порядкозависимую" ф-ю одной переменной? - та же конкатенация// Что делать в таком случае? (мыслится например агрегатная ф-я с объявленным пользователем типом данных, который, в свою очередь, приготавливается из пары (более) полей... Если это так, то так-же, видимо, можно передавать параметр и в первом случае?).


Извиняюсь что полез в "надуманные" проблемы, но столкнувшись с "гуру" хотелось бы посмотреть на приемы работы (именно с postgreSQL).

__
PS в каком порядке агрегатная функция обрабатывает данные? Можно ли настоять на собственном порядке? (скажем - телефоны сцеплять в строку с разделителем в порядке возрастания). Например, упорядочив входной набор данных, передаваемых на агрегирование?
___
ЗЫ

"If the state transition function was created with the isstrict attribute (see CREATE FUNCTION"), it cannot be called with NULL parameters. Transition functions declared in this manner cause aggregate execution to behave differently then normal; specifically, all NULL input parameters are ignored, and the function is not called. The previous state value is retained, and the aggregate function continues to process input values."

=>правильно ли понимать, что достаточно в фукции my_cat(char,char) оставить проверку на '' а проверку на null переложить на предложение WITH ( attribute [, ...] ), т.е. закончив обявление {create function my_cat(char,char)...}предлжением {WITH ristrict}?

Еще раз спасибо.
LeXa NalBat
Дата: 28.08.2003 12:00:02
Выскажу свои соображения не претендуя на звание гуру.

"нет способа объявления агрегатной функции с некоторым параметром"

Вроде бы так и есть. Можно попробовать сделать это например используя composite type или array type или как предложили Вы или еще как-то, но мне кажется что все это похоже на костыли и, возможно, правильнее было бы, если бы агрегатная функция могла иметь более одного аргумента, и эти аргументы передавались бы в sfunc и finalfunc. Это, видимо, решило бы и задачу создания агрегатной функции по нескольким полям.

"в каком порядке агрегатная функция обрабатывает данные"

Думаю, что в порядке поступления записей, определяемым планом запроса. Можно попытаться "запинать" план, но это не даст 100% гарантии, что план не испортится в процессе дальнейшей работы.

# create table table1 ( field1 varchar (16), field2 varchar(16) );
CREATE TABLE
# create index index1 on table1 ( field1, field2 );
CREATE INDEX
# explain select field1, pr_cat( field2 ) from table1 group by field1;
QUERY PLAN
--------------------------------------------------------------------------------------
Aggregate (cost=0.00..57.00 rows=100 width=40)
-> Group (cost=0.00..54.50 rows=1000 width=40)
-> Index Scan using index1 on table1 (cost=0.00..52.00 rows=1000 width=40)

"проверку на null переложить на предложение WITH ( attribute [, ...] )"

Да, вроде бы можно так сделать: "STRICT" или "WITH isStrict".
centur
Дата: 15.12.2004 22:01:02
поднима старое - но может кому поможет


собственно в вышеуказанном букваре именно такой пример
Examples

The following example defines an aggregate function named sum(), for use with the text data type. This aggregate calls the textcat(text,text) function built into PostgreSQL to return a concatenated "sum" of all the text found in its input values:

booktown=# CREATE AGGREGATE sum ( BASETYPE = text,
booktown(#                        SFUNC = textcat,
booktown(#                        STYPE = text,
booktown(#                        INITCOND = '' );
CREATE
booktown=# SELECT [color=red]sum(title || ' ')[/color] FROM books WHERE title ~ '^L';
              sum
-------------------------------
 Little Women Learning Python
(1 row)



где вторую переменную варьируют, т.е. хочешь пробел, хочешь запятую . Решаем вышеуказанный вопрос номер 1
centur
Дата: 15.12.2004 22:02:03
пытался выделить цветом а nested tags нету =(( смотреть на вызов функции sum