Подтвердить что ты не робот

Пользовательский ORDER BY Explanation

Я нашел это некоторое время назад и использовал его с тех пор; однако, глядя на него сегодня, я понял, что я не совсем понимаю, почему он работает. Может ли кто-то пролить свет на него для меня?

ORDER BY  s.type!= 'Nails',
          s.type!= 'Bolts',
          s.type!= 'Washers',
          s.type!= 'Screws',
          s.type!= 'Staples',
          s.type!= 'Nuts', ...

Если я заказываю по s.type, он упорядочивает по алфавиту. Если я использую пример выше, он использует тот же порядок, что и позиции строк. То, что я не понимаю, это использование! =. Если я использую =, он появляется в обратном порядке. Я не могу окунуться в концепцию этого.

Мне было бы разумно, что использование = вместо the!= выше поставило бы Nails на первое место, но это не так, оно помещает его в последнее. Я предполагаю, что мой вопрос таков: почему я должен использовать! =, Not = в этой ситуации?

4b9b3361

Ответ 1

Я никогда не видел его, но, похоже, имеет смысл.

Сначала он заказывает s.type != 'Nails'. Это false для каждой строки, содержащей Nails в столбце type. После этого он сортируется по Bolts. Опять же для всех столбцов, которые содержат Bolts как type, это оценивается как false. И так далее.

Небольшой тест показывает, что false упорядочен до true. Итак, у вас есть следующее: сначала вы получаете все строки с Nails сверху, потому что первый ORDER BY, оцененный как false и false. Остальные строки сортируются по второму критерию ORDER BY. И так далее.

 type     | != Nails | != Bolts | != Washers
'Nails'   | false    | true     | true
'Bolts'   | true     | false    | true
'Washers' | true     | true     | false

Ответ 2

Каждое выражение оценивается как bool и обрабатывается как 0 для false и 1 для true и сортируется соответствующим образом. Несмотря на то, что это работает, логика трудно следовать (и тем самым поддерживать). Я использую функцию, которая находит индекс значения в массиве.

ORDER BY idx(array['Nails','Bolts','Washers','Screws','Staples','Nuts'], s.type)

Это намного проще. Сначала гвозди будут отсортированы, а орехи отсортированы последними. Вы можете увидеть, как создать функцию idx в репозитории фрагментов Postgres. http://wiki.postgresql.org/wiki/Array_Index

Ответ 3

@Scott Bailey предложил отличную идею. Но это может быть еще проще (вам не нужно создавать пользовательскую функцию), поскольку PostgreSQL 9.5. Просто используйте array_position:

ORDER BY array_position(array['Nails','Bolts','Washers','Screws','Staples','Nuts'], s.type)

Ответ 4

с array_position, он должен иметь тот же тип, с которым вы запрашиваете.

например:

select array_position(array['foo'::char,'bar','baz'::char], 'bar');
select array_position(array['foo'::char,'bar','baz'::char], 'baz'::char);