Упорядочить по значению произвольного атрибута в hstore

У меня есть такие записи:

id, hstore_col
1,  {a: 1, b: 2}
2,  {c: 3, d: 4}
3,  {e: 1, f: 5}

Как упорядочить их по максимальному/минимальному значению внутри hstore для любого атрибута?

Результат должен быть таким (в порядке убывания):

id, hstore_col
1,  {a: 1, b: 2}
3,  {e: 1, f: 5}
2,  {c: 3, d: 4}

Я знаю, я могу упорядочить их только по определенному атрибуту, например: my_table.hstore_fields -> 'a', но это не работает для моей проблемы.


person Alexander    schedule 27.10.2014    source источник


Ответы (3)


Преобразуйте в массив, используя avals, и преобразуйте полученный массив из текста в целые числа. Затем отсортируйте массив и упорядочите результаты по 1-му элементу отсортированного массива.

select * from mytable
order by (sort(avals(attributes)::int[]))[1]

http://sqlfiddle.com/#!15/84f31/5

person FuzzyTree    schedule 27.10.2014
comment
Означает ли это, что ORDER BY great(avals(attributes)::int[]) также будет работать? - person Kirk Roybal; 27.10.2014
comment
@KirkRoybal это не сработает, потому что greatest возвращает наибольший из своих аргументов и будет рассматривать массив как один аргумент. - person FuzzyTree; 27.10.2014

Если вы знаете все элементы, вы можете просто собрать их вместе следующим образом:

ORDER BY greatest(my_table.hstore_fields -> 'a', my_table.hstore_fields -> 'b',my_table.hstore_fields -> 'c', my_table.hstore_fields -> 'd', my_table.hstore_fields -> 'e', my_table.hstore_fields -> 'f')

or

ORDER BY least(my_table.hstore_fields -> 'a', my_table.hstore_fields -> 'b',my_table.hstore_fields -> 'c', my_table.hstore_fields -> 'd', my_table.hstore_fields -> 'e', my_table.hstore_fields -> 'f')
person Kirk Roybal    schedule 27.10.2014

Используя svals, вы можете создать развернутую версию значений hstore_col, а затем отсортировать эти значения и получить первую запись для каждого из них. Несомненно, есть намного более эффективный способ сделать это, но вот первый вариант:

select my_table.id, my_table.hstore_col
from my_table
join (
    select id, svals(hstore_col) as hstore_val
    from my_table
) exploded_table
    on my_table.id = exploded_table.id
group by my_table.id, my_table.hstore_col
order by my_table.id, exploded_table.hstore_val desc
person Sean Vieira    schedule 27.10.2014