SQL - сохранить порядок на основе параметров запроса - PullRequest
5 голосов
/ 04 мая 2011

Я пытаюсь выполнить SELECT с предложением IN, и я хотел бы иметь возможность возвращать результаты в том же порядке, что и элементы в моем списке для IN. Например:

SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932', ...);

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

SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932', ...)
ORDER BY ('B123', 'B483', 'B100', 'B932', ...);

Я видел примеры запросов, использующих ключевые слова CASE или DECODE для определения своего рода пользовательского порядка. Но во всех этих примерах их порядок соответствовал заранее заданному набору параметров. Принимая во внимание, что мой заказ полностью зависит от того, что мой пользователь вводит для своих критериев поиска, так что может быть список из 2 вариантов или список из 100 для заказа по ...

Есть идеи? Некоторые функции Oracle, о которых я не знаю, или какой-то способ использования CASE или DECODE для динамического набора?

Ответы [ 7 ]

4 голосов
/ 04 мая 2011

Вставьте значения во временную таблицу и присоедините ваш выбор к этому.

Затем вы можете сделать естественный порядок для столбца временной таблицы.

CREATE GLOBAL TEMPORARY TABLE sort_table (
  value       VARCHAR2(100),
  sort_order  NUMBER
) ON COMMIT DELETE ROWS;

INSERT INTO sort_table VALUES ('B123',1);
INSERT INTO sort_table VALUES ('B483',2);
... etc. ...

select * from mytable
inner join sort_table
on mytable.mycolumn = sort_table.value
order by sort_table.sort_order;

Чтобы очистить временную таблицу, просто COMMIT.

2 голосов
/ 19 февраля 2014

вы можете попробовать это будет работать нормально. Проверьте ниже sql: -

SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932') 
ORDER BY DECODE(order_no,'B123','1','B483','2','B100','3','B932','4');
2 голосов
/ 04 мая 2011

Я не знаю, есть ли элегантное (или короткое) решение для этого.

Если вы можете построить запрос динамически, должно работать следующее:

WITH numbers AS (
   SELECT 1 as sort_order, 'B123' as order_no FROM DUAL
   union all
   SELECT 2 as sort_order, 'B483' as order_no FROM DUAL
   union all
   SELECT 2 as sort_order, 'B100' as order_no FROM DUAL
   union all
   SELECT 2 as sort_order, 'B932' as order_no FROM DUAL
)
SELECT orders.*
FROM numbers  
  LEFT JOIN orders ON orders.ord_no = numbers.ord_no
ORDER BY numbers.sort_order
1 голос
/ 09 января 2013

Если вы хотите использовать DECODE для назначения числового порядка сортировки:

SELECT ID FROM tbl WHERE ID IN (2,3,1)
ORDER BY DECODE(ID, 2, 1, 3, 2, 3)
1 голос
/ 05 мая 2011

Вы можете объединить свои переменные и упорядочить по ним, как показано ниже.Я не могу поручиться за эффективность этого, но, должно быть, это хорошо. Вашему внешнему интерфейсу, очевидно, придется проделать немного больше работы. Но построение такого запроса может быть открыто для sql Injection.

SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932', ...)
ORDER BY 
  instr ('@B123@'|| '@B483@'||'@B100@'||'@B932@'||... ,'@'|| order_no||'@')
0 голосов
/ 09 января 2013

Я сделал ответ здесь в более недавнем вопросе

https://stackoverflow.com/questions/14234748/preserve-rows-order-in-select-query-as-same-in-statement

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

0 голосов
/ 04 мая 2011

Я не парень из Python, но вот как я это сделаю в PHP, и я надеюсь, что вы поняли идею.

  1. Создайте строку, подобную этой:

    $ str = "('B123', 'B483', 'B100', 'B932', ...)";

    Выше можно использовать цикл for или что-то еще для построения действительно длинной строки.

  2. Вставьте строку в запрос следующим образом:

$MyQuery = "SELECT * FROM orders WHERE order_no IN $str
ORDER BY $str";

Как я уже сказал, это пример PHP, но я верю, что вы поняли идею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...