2015-04-01 8 views
0

Я хочу создать динамический порядок по выражению.ORDER BY с предложением CASE

Его цель - прочитать таблицу ежедневных переопределений (от 0 до * записей) и принять решение об использовании глобального переопределения или переопределения магазина для выбранного дня.

Я думал о том, чтобы использовать аргумент case, как показано ниже, но он не работает должным образом.

select * from schedule sdl 
where day = 3 
and (sdl.store_id = 23331 or sdl.store_id is null) 
order by 
case when sdl.force is true 
then 'sdl.store_id nulls first' 
else 'sdl.store_id nulls last' 
end 
limit 1 

Возможно ли создать заявление-заявление с использованием заявления о случаях? Или, может быть, есть лучший подход к этому вопросу.

+0

Я думаю, что кто-то ответил на этот вопрос: http://stackoverflow.com/questions/10645131/sql-case-statement-in-order-by- статья – IHTS

ответ

1

Вы, казалось, на правильном пути. Вам просто нужно создать значение для каждой строки и сделать его значимым для того, как вы хотите, чтобы они отсортировались.

select * 
from schedule sdl 
where day = 3 
    and (sdl.store_id = 23331 or sdl.store_id is null) 
order by case when sdl.store_id is null and sdl.force then 0 --nulls in front 
      when sdl.store_id is null and not sdl.force then 2 --nulls in back 
      else 1 end; --everything else in the middle 

Проверено на PostgreSQL 9.4.1

+0

Просто, чтобы внести свой вклад в ваш ответ. Если вы хотите получить другой порядок для средних результатов вместо 1 -> else row_number() over (partition by primary_key_id order by primary_key_id desc) end – mallix

+0

Это просто «упорядочило» строки в том же порядке, который появился в результат набор. Просто имея три значения 0 для «Nulls first», 1 для «Non-nulls» и 2 для «Nulls last» обеспечивает больше эффекта группировки, позволяя более упорядочить по критериям, чтобы обеспечить разумный порядок в каждой группе. – TommCatt

+0

Не говоря уже о том, что значение 2 больше не может использоваться для группы «Nulls last». Вам нужно будет каким-то образом отслеживать количество сгенерированных номеров строк и установить его на некоторое значение, большее, чем номер последней строки. – TommCatt

-2

Попробуйте использовать регистр в предложении select и затем сортировать его по этому полю.

Без тестирования я должен выглядеть примерно так, что

select *, 
case when sdl.force is true 
    then 'sdl.store_id nulls first' 
    else 'sdl.store_id nulls last' 
    end as orderfield 
from schedule sdl 
where day = 3 
and (sdl.store_id = 23331 or sdl.store_id is null) 
order by orderfield 
limit 1 
+0

Можете ли вы опубликовать или ссылку на код? – mallix

+0

Я не думаю, что это действительно. 'sdl.store_id nulls first' :: text, поэтому он интерпретируется как текст, а не фактическая ссылка store_id – mallix

+0

oh yes is see Я забыл сначала значения nulls и nulls last. извините –

0

да это возможно, ссылка на комментарий к вашему вопросу показывает правильный пример, но он выглядит как ваш вопрос «обнуляет первый/последний» , Это недействительные конструкции postgres. Ваш запрос должен быть как

select * from schedule sdl 
where day = 3 and (sdl.store_id = 23331 or sdl.store_id is null) 
order by 
case when sdl.force is true 
    then sdl.store_id end desc, 
case when sdl.force is false 
    then sdl.store_id end   
limit 1 

по возрастанию по умолчанию сортировка (не требуется указывать явно)

Смежные вопросы