Обсуждение: Аналог distinct для массива

Поиск
Список
Период
Сортировка

Аналог distinct для массива

От
Dmitriy MiksIr
Дата:
   Приветствую!

   Есть необходимость выбирать уникальные значения из всей таблицы по
полю integer[] (уникальные как по строкам, так и по массиву). Делаю
сейчас это так (кусок функции):
  SELECT max(array_upper(marks,1)) INTO size FROM firms WHERE ...;
  FOR resrow IN
    SELECT distinct(f.marks[g.n]) as result
      FROM firms f, generate_series(1,size) g(n) WHERE ...;
  ...
Не очень нравится такое решение своей красотой (ибо если, например, одна
строка - 100 элементов массива, а остальные - по 2-3, получается очень
накладно). Может есть другие решения?

Re: Аналог distinct для массива

От
Oleg Bartunov
Дата:
Если это integer arrays, то есть
http://www.sai.msu.su/~megera/postgres/gist/intarray/README.intarray
Заодно получишь много чего приятного :)

Олег
On Thu, 21 Feb 2008, Dmitriy MiksIr wrote:

>
>  Приветствую!
>
>  Есть необходимость выбирать уникальные значения из всей таблицы по полю
> integer[] (уникальные как по строкам, так и по массиву). Делаю сейчас это так
> (кусок функции):
> SELECT max(array_upper(marks,1)) INTO size FROM firms WHERE ...;
> FOR resrow IN
>   SELECT distinct(f.marks[g.n]) as result
>     FROM firms f, generate_series(1,size) g(n) WHERE ...;
> ...
> Не очень нравится такое решение своей красотой (ибо если, например, одна
> строка - 100 элементов массива, а остальные - по 2-3, получается очень
> накладно). Может есть другие решения?
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: Have you checked our extensive FAQ?
>
>              http://www.postgresql.org/docs/faq
>

     Regards,
         Oleg
_____________________________________________________________
Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
Sternberg Astronomical Institute, Moscow University, Russia
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(495)939-16-83, +007(495)939-23-83

Re: Аналог distinct для массива

От
Dmitriy MiksIr
Дата:
Да, но того что может помочь не нашел. Может смотрел не туда.

Единственная идея, что появилась - это сложить как-то все массивы по
строкам, и на итоговый сказать uniq ... но красивая реализация в голову
не идет.

Или написать функцию, которая будет раскрывать масив и выдавать
результат как набор строк, т.е.
arr     | other
[1,2,3] | bla
преобразовывать в
1 | bla
2 | bla
3 | bla
только можно ли силами plpgsql пройтись циклом по массиву?

Oleg Bartunov пишет:
> Если это integer arrays, то есть
> http://www.sai.msu.su/~megera/postgres/gist/intarray/README.intarray
> Заодно получишь много чего приятного :)
>
> Олег
> On Thu, 21 Feb 2008, Dmitriy MiksIr wrote:
>
>>
>>  Приветствую!
>>
>>  Есть необходимость выбирать уникальные значения из всей таблицы по
>> полю integer[] (уникальные как по строкам, так и по массиву). Делаю
>> сейчас это так (кусок функции):
>> SELECT max(array_upper(marks,1)) INTO size FROM firms WHERE ...;
>> FOR resrow IN
>>   SELECT distinct(f.marks[g.n]) as result
>>     FROM firms f, generate_series(1,size) g(n) WHERE ...;
>> ...
>> Не очень нравится такое решение своей красотой (ибо если, например,
>> одна строка - 100 элементов массива, а остальные - по 2-3, получается
>> очень накладно). Может есть другие решения?
>>
>>
>> ---------------------------(end of broadcast)---------------------------
>> TIP 3: Have you checked our extensive FAQ?
>>
>>              http://www.postgresql.org/docs/faq
>>
>
>     Regards,
>         Oleg
> _____________________________________________________________
> Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
> Sternberg Astronomical Institute, Moscow University, Russia
> Internet: oleg@sai.msu.su,
> http://www.sai.msu.su/~megera/
> phone: +007(495)939-16-83, +007(495)939-23-83
> ---------------------------(end of broadcast)---------------------------
> TIP 9: In versions below 8.0, the planner will ignore your desire to
>       choose an index scan if your joining column's datatypes do not
>       match
>

Re: Re: Аналог distinct для массива

От
Oleg Bartunov
Дата:
On Thu, 21 Feb 2008, Dmitriy MiksIr wrote:

> Да, но того что может помочь не нашел. Может смотрел не туда.

там есть функция uniq

>
> Единственная идея, что появилась - это сложить как-то все массивы по строкам,
> и на итоговый сказать uniq ... но красивая реализация в голову не идет.
>
> Или написать функцию, которая будет раскрывать масив и выдавать результат как
> набор строк, т.е.
> arr     | other
> [1,2,3] | bla
> преобразовывать в
> 1 | bla
> 2 | bla
> 3 | bla
> только можно ли силами plpgsql пройтись циклом по массиву?
>
> Oleg Bartunov пишет:
>> Если это integer arrays, то есть
>> http://www.sai.msu.su/~megera/postgres/gist/intarray/README.intarray
>> Заодно получишь много чего приятного :)
>>
>> Олег
>> On Thu, 21 Feb 2008, Dmitriy MiksIr wrote:
>>
>>>
>>>  Приветствую!
>>>
>>>  Есть необходимость выбирать уникальные значения из всей таблицы по полю
>>> integer[] (уникальные как по строкам, так и по массиву). Делаю сейчас это
>>> так (кусок функции):
>>> SELECT max(array_upper(marks,1)) INTO size FROM firms WHERE ...;
>>> FOR resrow IN
>>>   SELECT distinct(f.marks[g.n]) as result
>>>     FROM firms f, generate_series(1,size) g(n) WHERE ...;
>>> ...
>>> Не очень нравится такое решение своей красотой (ибо если, например, одна
>>> строка - 100 элементов массива, а остальные - по 2-3, получается очень
>>> накладно). Может есть другие решения?
>>>
>>>
>>> ---------------------------(end of broadcast)---------------------------
>>> TIP 3: Have you checked our extensive FAQ?
>>>
>>>              http://www.postgresql.org/docs/faq
>>>
>>
>>     Regards,
>>         Oleg
>> _____________________________________________________________
>> Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
>> Sternberg Astronomical Institute, Moscow University, Russia
>> Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
>> phone: +007(495)939-16-83, +007(495)939-23-83
>> ---------------------------(end of broadcast)---------------------------
>> TIP 9: In versions below 8.0, the planner will ignore your desire to
>>       choose an index scan if your joining column's datatypes do not
>>       match
>>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 6: explain analyze is your friend
>

     Regards,
         Oleg
_____________________________________________________________
Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
Sternberg Astronomical Institute, Moscow University, Russia
Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/
phone: +007(495)939-16-83, +007(495)939-23-83

Re: Аналог distinct для массива

От
Dmitriy MiksIr
Дата:
У меня другая задача немного. На примере, имеем записи:
[1,2,3]
[3,4]
[2,6]
нужно получить или один массив [1,2,3,4,6] или набор int-ов
1
2
3
4
6

Приходит в голову
     FOR resrow IN
       SELECT marks
         FROM firms WHERE ...
     LOOP
       SELECT array_cat(carr,resrow.marks) INTO carr;
     END LOOP;
и потом на carr натравить uniq... возможно это будет красивее, чем
вариант ниже.


А то, что в intarray описан оператор && который уже есть в 8.2 - не страшно?


Oleg Bartunov пишет:
> On Thu, 21 Feb 2008, Dmitriy MiksIr wrote:
>
>> Да, но того что может помочь не нашел. Может смотрел не туда.
>
> там есть функция uniq
>
>>
>> Единственная идея, что появилась - это сложить как-то все массивы по
>> строкам, и на итоговый сказать uniq ... но красивая реализация в
>> голову не идет.
>>
>> Или написать функцию, которая будет раскрывать масив и выдавать
>> результат как набор строк, т.е.
>> arr     | other
>> [1,2,3] | bla
>> преобразовывать в
>> 1 | bla
>> 2 | bla
>> 3 | bla
>> только можно ли силами plpgsql пройтись циклом по массиву?
>>
>> Oleg Bartunov пишет:
>>> Если это integer arrays, то есть
>>> http://www.sai.msu.su/~megera/postgres/gist/intarray/README.intarray
>>> Заодно получишь много чего приятного :)
>>>
>>> Олег
>>> On Thu, 21 Feb 2008, Dmitriy MiksIr wrote:
>>>
>>>>
>>>>  Приветствую!
>>>>
>>>>  Есть необходимость выбирать уникальные значения из всей таблицы по
>>>> полю integer[] (уникальные как по строкам, так и по массиву). Делаю
>>>> сейчас это так (кусок функции):
>>>> SELECT max(array_upper(marks,1)) INTO size FROM firms WHERE ...;
>>>> FOR resrow IN
>>>>   SELECT distinct(f.marks[g.n]) as result
>>>>     FROM firms f, generate_series(1,size) g(n) WHERE ...;
>>>> ...
>>>> Не очень нравится такое решение своей красотой (ибо если, например,
>>>> одна строка - 100 элементов массива, а остальные - по 2-3,
>>>> получается очень накладно). Может есть другие решения?
>>>>
>>>>
>>>> ---------------------------(end of
>>>> broadcast)---------------------------
>>>> TIP 3: Have you checked our extensive FAQ?
>>>>
>>>>              http://www.postgresql.org/docs/faq
>>>>
>>>
>>>     Regards,
>>>         Oleg
>>> _____________________________________________________________
>>> Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
>>> Sternberg Astronomical Institute, Moscow University, Russia
>>> Internet: oleg@sai.msu.su,
>>> http://www.sai.msu.su/~megera/
>>> phone: +007(495)939-16-83, +007(495)939-23-83
>>> ---------------------------(end of broadcast)---------------------------
>>> TIP 9: In versions below 8.0, the planner will ignore your desire to
>>>       choose an index scan if your joining column's datatypes do not
>>>       match
>>>
>>
>>
>> ---------------------------(end of broadcast)---------------------------
>> TIP 6: explain analyze is your friend
>>
>
>     Regards,
>         Oleg
> _____________________________________________________________
> Oleg Bartunov, Research Scientist, Head of AstroNet (www.astronet.ru),
> Sternberg Astronomical Institute, Moscow University, Russia
> Internet: oleg@sai.msu.su,
> http://www.sai.msu.su/~megera/
> phone: +007(495)939-16-83, +007(495)939-23-83
> ---------------------------(end of broadcast)---------------------------
> TIP 1: if posting/reading through Usenet, please send an appropriate
>       subscribe-nomail command to
> majordomo@postgresql.org so that your
>       message can get through to the mailing list cleanly
>