sql ORDER BY несколько значений в определенном порядке? - PullRequest
72 голосов
/ 13 июня 2011

Хорошо, у меня есть таблица с индексированным ключом и неиндексированным полем.Мне нужно найти все записи с определенным значением и вернуть строку.Я хотел бы знать, могу ли я упорядочить по нескольким значениям.

Пример:

id     x_field
--     -----
123    a
124    a
125    a
126    b
127    f
128    b
129    a
130    x
131    x
132    b
133    p
134    p
135    i

псевдо: хотел бы, чтобы результаты были упорядочены следующим образом, where ORDER BY x_field = 'f', 'p', 'i', 'a'

SELECT *
FROM table
WHERE id NOT IN (126)
ORDER BY x_field 'f', 'p', 'i', 'a'

Таким образом, результаты будут такими:

id     x_field
--     -----
127    f
133    p
134    p
135    i
123    a
124    a
125    a
129    a

Синтаксис действителен, но когда я выполняю запрос, он никогда не возвращает никаких результатов, даже если я ограничиваю его 1 записью.Есть ли другой способ сделать это?

Думайте о x_field как о результатах теста, и мне нужно проверить все записи, которые попадают в условие.Я хотел упорядочить результаты теста по ошибочным значениям, переданным значениям.Таким образом, я мог сначала проверить ошибочные значения, а затем переданные значения, используя ORDER BY.

Что я не могу сделать:

  • GROUP BY, так как мне нужно вернуть конкретныйзначения записи
  • ГДЕ x_field IN ('f', 'p', 'i', 'a'), мне нужны все значения, так как я пытаюсь использовать один запрос для нескольких проверочных тестов.И значения x_field не в порядке DESC / ASC

После написания этого вопроса я начинаю думать, что мне нужно переосмыслить это, LOL!

Ответы [ 8 ]

143 голосов
/ 13 июня 2011
...
WHERE
   x_field IN ('f', 'p', 'i', 'a') ...
ORDER BY
   CASE x_field
      WHEN 'f' THEN 1
      WHEN 'p' THEN 2
      WHEN 'i' THEN 3
      WHEN 'a' THEN 4
      ELSE 5 --needed only is no IN clause above. eg when = 'b'
   END, id
23 голосов
/ 14 июня 2011

Вы можете использовать левое соединение с «VALUES ('f', 1), ('p', 2), ('a', 3), ('i', 4)" и использовать второй столбец в вашем порядке по выражению. Postgres будет использовать Hash Join, который будет намного быстрее, чем огромный CASE, если у вас много значений. И это проще для генерации.

Если эта информация о заказе исправлена, то она должна иметь свою собственную таблицу.

19 голосов
/ 13 июня 2011

Попробуйте:

ORDER BY x_field='F', x_field='P', x_field='A', x_field='I'

Вы были на правильном пути, но, поместив x_field только на значение F, остальные 3 рассматривались как константы и не сравнивались ни с чем в наборе данных.

12 голосов
/ 13 июня 2011

Используйте переключатель case для перевода кодов в числа, которые можно отсортировать:

ORDER BY
  case x_field
  when 'f' then 1
  when 'p' then 2
  when 'i' then 3
  when 'a' then 4
  else 5
  end
6 голосов
/ 24 ноября 2018

Я нашел гораздо более чистое решение для этого:

ORDER BY array_position(ARRAY['f', 'p', 'i', 'a']::varchar[], x_field)

Примечание: для array_position требуется Postgres v9.5 или выше.

6 голосов
/ 13 июня 2011

Предложения CASE и ORDER BY должны работать, но я собираюсь предложить лошадь другого цвета. Предполагая, что существует только разумное количество значений для x_field, и вы уже знаете, что это такое, создайте перечислимый тип с F, P, A и I в качестве значений (плюс любые другие возможные значения применять). Перечисления сортируются в порядке, подразумеваемом оператором CREATE. Кроме того, вы можете использовать имена значимых значений & ndash; ваше реальное приложение, вероятно, использует это, и вы только что замаскировали их для конфиденциальности & mdash; без потери места, поскольку сохраняется только порядковая позиция.

0 голосов
/ 27 апреля 2019

Вы можете упорядочить по выбранному столбцу или другим выражениям.

Вот пример того, как упорядочить по результату оператора case:

  SELECT col1
       , col2
    FROM tbl_Bill
   WHERE col1 = 0
ORDER BY -- order by case-statement
    CASE WHEN tbl_Bill.IsGen = 0 THEN 0
         WHEN tbl_Bill.IsGen = 1 THEN 1
         ELSE 2 END

Результатом будетСписок начинается со строк «IsGen = 0», за которыми следуют строки «IsGen = 1» и все остальные строки в конце.

В конце можно добавить дополнительные параметры порядка:

  SELECT col1
       , col2
    FROM tbl_Bill
   WHERE col1 = 0
ORDER BY -- order by case-statement
    CASE WHEN tbl_Bill.IsGen = 0 THEN 0
         WHEN tbl_Bill.IsGen = 1 THEN 1
         ELSE 2 END,
         col1,
         col2
0 голосов
/ 15 января 2018

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

...