У меня есть простой SQL-запрос в PostgreSQL 8.3, который собирает кучу комментариев. Я предоставляю отсортированный список значений для IN
конструкции в WHERE
предложении:
SELECT * FROM comments WHERE (comments.id IN (1,3,2,4));
Это возвращает комментарии в произвольном порядке, который в моем случае похож на id 1,2,3,4
.
Я хочу , чтобы получившиеся строки , упорядоченные как список в IN
конструкции: (1,3,2,4)
.
Как этого добиться?
sql
postgresql
sql-order-by
sql-in
щелкунчик
источник
источник
Ответы:
Вы можете сделать это довольно легко с (представлен в PostgreSQL 8.2) VALUES (), ().
Синтаксис будет таким:
источник
with ordered_products as (select row_number() OVER (ORDER BY whatever) as reportingorder, id from comments) ... ORDER BY reportingorder
.Просто потому, что его так сложно найти и нужно распространять: в MySQL это можно сделать гораздо проще , но я не знаю, работает ли он в другом SQL.
источник
ERROR: cannot pass more than 100 arguments to a function
В Postgres 9.4 или новее это, вероятно, самый простой и быстрый способ :
Используя новое
WITH ORDINALITY
, что @a_horse уже упоминалось .Нам не нужен подзапрос, мы можем использовать функцию возврата набора, как таблицу.
Строковый литерал, передаваемый в массив вместо конструктора ARRAY, может быть проще реализовать с некоторыми клиентами.
Детальное объяснение:
источник
Я думаю, что так лучше
источник
... order by id=? desc, id=? desc, id=? desc
и, кажется, работает нормально :-)С Postgres 9.4 это можно сделать немного короче:
Или немного более компактно без производной таблицы:
Снятие необходимости вручную назначать / поддерживать позицию для каждого значения.
С Postgres 9.6 это можно сделать с помощью
array_position()
:CTE используется так, что список значений должен быть указан только один раз. Если это не важно, это также можно записать так:
источник
IN
список изWHERE
предложения снова вORDER BY
предложении, что делает это лучшим ответом imho ... Теперь только чтобы найти что-то похожее для MySQL ...order by array_position(array[42,48,43], c.id::int);
которое может привести к ошибкам в некоторых случаях.array_position(array[42, 48, 43]::bigint[], c.id::bigint)
, в Postgres 12) , поэтому не нужно усекатьсяbigint
доint
.Другой способ сделать это в Postgres - использовать
idx
функцию.Не забудьте
idx
сначала создать функцию, как описано здесь: http://wiki.postgresql.org/wiki/Array_Indexисточник
CREATE EXTENSION intarray;
.enable_extension
позволит вам активировать эту функцию , пока пользователь вашего приложения является членомrds_superuser
группы.В Postgresql:
источник
position(id::text in '123,345,3,678')
. Идентификатор3
будет соответствовать перед идентификатором345
, не так ли?Исследуя это еще немного, я нашел это решение:
Однако это кажется довольно многословным и может иметь проблемы с производительностью с большими наборами данных. Кто-нибудь может прокомментировать эти вопросы?
источник
IN
? потому что я должен сделать это для тысяч записей.Для этого, я думаю, у вас, вероятно, должна быть дополнительная таблица «ORDER», которая определяет отображение идентификаторов в порядке (эффективно выполняющих то, что сказал ваш ответ на ваш собственный вопрос), которую вы затем можете использовать в качестве дополнительного столбца по вашему выбору, который Вы можете сортировать дальше.
Таким образом, вы явно описываете порядок, который вы хотите в базе данных, где это должно быть.
источник
sans SEQUENCE, работает только на 8.4:
источник
или если вы предпочитаете зло добру
источник
А вот еще одно решение, которое работает и использует постоянную таблицу ( http://www.postgresql.org/docs/8.3/interactive/sql-values.html ):
Но опять же я не уверен, что это эффективно.
У меня есть куча ответов сейчас. Могу ли я получить голосование и комментарии, чтобы я знал, кто победит!
Спасибо всем :-)
источник
[РЕДАКТИРОВАТЬ]
unnest еще не встроен в 8.3, но вы можете создать его самостоятельно (прелесть любого *):
эта функция может работать в любом типе:
источник
Небольшое улучшение по сравнению с версией, которая использует последовательность, я думаю:
источник
здесь [bbs] - главная таблица, которая имеет поле с именем ids, а ids - массив, в котором хранится comments.id.
прошло в postgresql 9,6
источник
Позволяет получить визуальное представление о том, что уже было сказано. Например, у вас есть таблица с некоторыми задачами:
И вы хотите упорядочить список задач по его статусу. Статус представляет собой список строковых значений:
Хитрость заключается в том, чтобы присвоить каждому значению состояния целое число и упорядочить список по порядку:
Что приводит к:
Credit @ user80168
источник
Я согласен со всеми другими авторами, которые говорят «не делай этого» или «SQL не хорош в этом». Если вы хотите отсортировать по некоторому фасету комментариев, добавьте еще один целочисленный столбец в одну из ваших таблиц, чтобы сохранить критерии сортировки и отсортировать по этому значению. например, "ORDER BY comments.sort DESC" Если вы хотите сортировать их каждый раз в другом порядке, тогда ... SQL в этом случае не подойдет вам.
источник