Мне интересно, есть ли возможность (возможно, лучший способ) упорядочить по порядку значений в предложении IN ().
Проблема в том, что у меня есть 2 запроса, один из которых получает все идентификаторы, а второй - всю информацию. Первый создает порядок идентификаторов, по которым я хочу, чтобы второй упорядочил. Идентификаторы помещаются в предложение IN () в правильном порядке.
Так что это будет что-то вроде (очень упрощенно):
SELECT id FROM table1 WHERE ... ORDER BY display_order, name
SELECT name, description, ... WHERE id IN ([id's from first])
Проблема заключается в том, что второй запрос не возвращает результаты в том же порядке, в котором идентификаторы помещены в предложение IN ().
Одно решение, которое я нашел, состоит в том, чтобы поместить все идентификаторы во временную таблицу с автоматически возрастающим полем, которое затем присоединяется ко второму запросу.
Есть ли лучший вариант?
Примечание. Поскольку первый запрос выполняется «пользователем», а второй - в фоновом процессе, невозможно объединить запрос 2 в 1, используя подзапросы.
Я использую MySQL, но думаю, что было бы полезно отметить, какие есть варианты и для других БД.
источник
IN
иFIELD
параметры равны. Выполнение этого в программном коде может быть быстрее с использованием этих дополнительных знаний. Конечно, разумнее было бы возложить это бремя на клиента, а не на сервер, если учитывать производительность сервера.sqlite
?Смотрите ниже, как получить отсортированные данные.
источник
Два решения, которые приходят на ум:
order by case id when 123 then 1 when 456 then 2 else null end asc
order by instr(','||id||',',',123,456,') asc
(
instr()
от Oracle; может быть, у вас естьlocate()
илиcharindex()
или что-то в этом роде)источник
Ответ, чтобы получить отсортированные данные.
источник
Если вы хотите выполнить произвольную сортировку запроса, используя значения, введенные запросом в MS SQL Server 2008+ , это можно сделать, создав таблицу на лету и выполнив объединение, как это делается (используя номенклатуру из OP).
Если вы замените оператор VALUES чем-то другим, что делает то же самое, но в ANSI SQL, это должно работать с любой базой данных SQL.
Примечание . Второй столбец в созданной таблице (orderTbl.orderIdx) необходим при запросе наборов записей больше 100 или около того. Изначально у меня не было столбца orderIdx, но я обнаружил, что с наборами результатов больше 100 мне пришлось явно сортировать по этому столбцу; в SQL Server Express 2014 в любом случае.
источник
orderTbl.orderKey
,orderTbl.orderIndex
поorderKey
,orderIndex
работал действительно здорово
источник
Предложение IN описывает набор значений, а наборы не имеют порядка.
Ваше решение с объединением и последующим заказом по
display_order
столбцу является наиболее правильным решением; все остальное, вероятно, является хаком, специфичным для СУБД (или делает что-то с функциями OLAP в стандартном SQL). Конечно, объединение является наиболее переносимым решением (хотя генерирование данных соdisplay_order
значениями может быть проблематичным). Обратите внимание, что вам может потребоваться выбрать столбцы заказа; это было требованием в стандартном SQL, хотя я полагаю, что это было смягчено, как правило, некоторое время назад (может быть, так же давно, как SQL-92).источник
Используйте функцию MySQL FIND_IN_SET :
источник
Для Oracle работает решение Джона с использованием функции instr (). Вот немного другое решение, которое сработало -
SELECT id FROM table1 WHERE id IN (1, 20, 45, 60) ORDER BY instr('1, 20, 45, 60', id)
источник
Я просто попытался сделать это MS SQL Server, где у нас нет FIELD ():
Обратите внимание, что я разрешаю дублирование тоже.
источник
Моей первой мыслью было написать один запрос, но вы сказали, что это невозможно, потому что один запускается пользователем, а другой - в фоновом режиме. Как вы храните список идентификаторов для передачи от пользователя к фоновому процессу? Почему бы не положить их во временную таблицу с колонкой для обозначения порядка.
Так как насчет этого:
источник
Я думаю, что вам нужно хранить свои данные таким образом, чтобы вы просто выполняли объединение, и оно было идеальным, поэтому никаких взломов и сложных вещей не происходит.
У меня есть, например, «Недавно воспроизведенный» список идентификаторов треков, на SQLite я просто делаю:
источник
Дайте этому шанс:
WHERE, возможно, потребуется немного изменить, чтобы правильно работать коррелированные подзапросы, но основной принцип должен быть надежным.
источник