[Moscow.pm] DBIx и свертка в массивы

Ruslan Zakirov ruz на bestpractical.com
Чт Авг 18 06:52:19 PDT 2011


2011/8/18 Oleg Kostyuk <cub.uanic на gmail.com>:
> Да, конечно читаю.
>
>
> Другое дело, что вы не смогли чётко сформулировать свой вопрос, потому
> как у вас нет четкого понимания того, как работает база, что она
> может, а что нет. И потому вы решили, что вам нужно решение с GROUP
> BY. Но здесь это не подойдет, потому как по указанным в GROUP BY
> столбцам происходит группировка, а к не указанным нужно ОБЯЗАТЕЛЬНО
> применять аггругирующие функции. Увы, но в классическом SQL нет такой
> аггрегирующей функции, чтоб из нескольких значений сделать одно, с
> типом "множество" и включающим все аггрегируемые данные. Потому
> решение в данном случае, как и предлагал Руслан, будет опираться на
> perl'овую сторону сильнее, чем на SQL'ную.

В класическом SQL нет и типа массив, но в Pg можно сделать свои
агрегирующие функции (пробовал) и даже _наверное_ (не пробовал) писать
их на Perl. Все очень просто описано на примере GROUP_CONCAT, которая
есть в MySQL из коробки, но нет в Pg:

http://mssql-to-postgresql.blogspot.com/2007/12/cool-groupconcat.html

Тут будет что-то типа

SELECT some, array_accum(id) FROM table;

Не уверен на сколько хорошо DBI::Pg поддерживает массивы.

Дополнительная причина использовать Perl, а не специальные функции БД
- портируемость между различными СУБД. Пример слишком примитивный и
элементарно решается на стороне приложения, чтобы ради этого потерять
портируемость.

Приведенная статья очень хороша опять же с точки зрения портируемости.
В Pg скорее всего можно написать любой агрегатор эмулирующий поведение
другой БД.

> Примерно, вот так (не тестировал):
>
> my %result = map {
>    $_->some => [
>        $rs->search(
>            {some => $_->some},
>            {
>                order_by => [qw/ id /],
>                columns => [qw/ id /],
>            }
>        )->get_column('id')->all
>    ]
> } $rs->search(
>    undef,
>    {
>        columns => [qw/ some /],
>        distinct => 1,
>    }
> )->all;
>

[snip]

-- 
Best regards, Ruslan.


Подробная информация о списке рассылки Moscow-pm