Ответ 1
...
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
Ok У меня есть таблица с индексированным ключом и индексированным полем. Мне нужно найти все записи с определенным значением и вернуть строку. Я хотел бы знать, могу ли я заказать несколько значений.
Пример:
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
pseudo: хотел бы, чтобы результаты были упорядочены следующим образом: 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.
Что я не могу сделать:
После написания этого вопроса я начинаю думать, что мне нужно переосмыслить это, LOL!
...
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
Вы можете использовать LEFT JOIN с "VALUES ('f', 1), ('p', 2), ('a', 3), ('i', 4)" и использовать второй столбец в вашем порядке - по выражению. Postgres будет использовать Hash Join, который будет намного быстрее, чем огромный CASE, если у вас много значений. И легче автогенерировать.
Если эта информация упорядочения фиксирована, тогда она должна иметь свою собственную таблицу.
Try:
ORDER BY x_field='F', x_field='P', x_field='A', x_field='I'
Вы были на правильном пути, но, поставив x_field только на значение F, остальные 3 были рассмотрены как константы и не сравнивались ни с чем в наборе данных.
Используйте переключатель 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
Предложения CASE
и ORDER BY
должны работать, но я собираюсь предложить лошадь другого цвета. Предполагая, что существует только разумное количество значений для x_field
и вы уже знаете, что это такое, создайте перечислимый тип с F, P, A и я в качестве значений (плюс любые другие возможные значения). Перечисления сортируются в порядке, подразумеваемом оператором CREATE
. Кроме того, вы можете использовать значимые имена значений - вероятно, ваше реальное приложение и вы только что замаскировали их для конфиденциальности - без лишних пробелов, поскольку сохраняется только порядковая позиция.
Я нашел намного более чистое решение для этого:
ORDER BY array_position(ARRAY['f', 'p', 'i', 'a']::varchar[], x_field)
Примечание: для array_position требуется Postgres v9.5 или выше.
Вы можете заказать по выбранному столбцу или другим выражениям.
Вот пример того, как упорядочить по результату 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
Вы можете использовать положение (текст в тексте) для упорядочения последовательности