Специальный ORDER BY с оператором CASE — требуется руководство

Я думаю о том, как мне нужно написать этот запрос. Я думаю, что это может включать CASE в операторе ORDER BY, но мне не помешало бы небольшое руководство.

У меня есть два столбца данных; ID и цена. Когда я ЗАКАЗЫВАЮ ПО цене ASC, результаты моего запроса выглядят примерно так:

ID | Цена
3 | 150
1 | 200
3 | 205
2 | 210
2 | 230
3 | 270
1 | 300
2 | 340
3 | 500

Что я хочу сделать, так это по-прежнему ЗАКАЗАТЬ по цене ASC, но с небольшим изменением. Я также хочу сгруппировать по идентификаторам. Например, я хотел бы, чтобы запрос нашел самую низкую цену из всех результатов, а затем нашел все другие записи с тем же идентификатором, перечисленные в порядке цен ASC. После того, как все записи для этого идентификатора будут найдены, запрос просматривает все остальные оставшиеся записи, снова находит самую низкую цену и повторяет. Таким образом, пул результатов будет уменьшаться каждый раз, когда он проходит через этот цикл. Для приведенного выше примера результатом будет:

ID | Цена
3 | 150
3 | 205
3 | 270
3 | 500
1 | 200
1 | 300
2 | 210
2 | 230
2 | 340

Цикл похож на поиск самой низкой цены, поиск всех записей с одинаковым идентификатором и перечисление в порядке цен, поиск самой низкой цены оставшихся результатов, поиск всех записей с одинаковым идентификатором и перечисление в порядке цен, повторение....

Любые идеи? Дайте мне знать, если я недостаточно хорошо объяснил.


person pkracer    schedule 05.03.2013    source источник
comment
Вам нужно будет сделать что-то вроде ORDER BY, а затем упорядочить по подзапросу/временной таблице, которая упорядочивает идентификаторы по их минимальной цене и создает столбец, который ранжирует их от 1 до N. И тогда вы можете просто связать свою строку ID с индексом этой подзапроса/временной таблицы, упорядочение по которому даст вам желаемый порядок. И тогда вы можете иметь вторичный порядок (как в порядке x, y) для субпорядка по цене.   -  person Patashu    schedule 05.03.2013


Ответы (3)


Вы используете Postgres, поэтому у вас есть оконные функции. Вот пример SQL, который вам нужен:

select id, price
from (select t.*,
             min(price) over (partition by id) as minprice
      from t
     ) t
order by minprice, id, price
person Gordon Linoff    schedule 05.03.2013

SELECT ID, PRICE
FROM t
ORDER BY MIN(PRICE) OVER (PARTITION BY ID), PRICE

скрипт SQL

person Amy B    schedule 05.03.2013
comment
Да, мне тоже нравится этот вариант. Очень прямо вперед. - person pkracer; 05.03.2013

скрипт SQL

select t.id, t.price
from
    t
    inner
    join (
        select row_number() over(order by price) o, id
        from (
            select id, min(price) price
            from t
            group by id
        ) s
    ) s on s.id = t.id
order by s.o, t.price
person Clodoaldo Neto    schedule 05.03.2013