Возврат результатов запроса в предопределенном порядке - PullRequest
15 голосов
/ 25 сентября 2008

Можно ли сделать оператор SELECT с предопределенным порядком, т.е. выбрать идентификаторы 7,2,5,9 и 8 и вернуть их в таком порядке , основываясь только на поле ID?

Операторы SELECT id из таблицы WHERE id в (7,2,5,9,8); и ВЫБЕРИТЕ идентификатор из таблицы ГДЕ идентификатор в (8,2,5,9,7); оба возвращают их в том же порядке.

Ответы [ 11 ]

36 голосов
/ 25 сентября 2008

Я не думал, что это было возможно, но нашел здесь запись в блоге , которая, кажется, делает то, что вам нужно:

SELECT id FROM table WHERE id in (7,2,5,9,8) 
ORDER BY FIND_IN_SET(id,"7,2,5,9,8");

даст разные результаты для

SELECT id FROM table WHERE id in (7,2,5,9,8) 
ORDER BY FIND_IN_SET(id,"8,2,5,9,7");

<a href="http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set" rel="noreferrer">FIND_IN_SET</a> возвращает позицию id во втором заданном ей аргументе, поэтому для первого случая выше, id из 7 находится в позиции 1 в наборе, 2 в 2 и так далее - mysql внутри получается что-то вроде

id | FIND_IN_SET
---|-----------
7  | 1
2  | 2
5  | 3

затем заказывает по результатам FIND_IN_SET.

3 голосов
/ 25 сентября 2008

ЗАКАЗ ПО ПОЛЯМ (ID, 7,2,4,5,8) - ваша лучшая ставка, но она все еще безобразна.

1 голос
/ 25 сентября 2008

Не могли бы вы включить выражение case, которое сопоставляет ваши идентификаторы 7,2,5, ... с порядковыми номерами 1,2,3, ..., а затем упорядочить по этому выражению?

0 голосов
/ 04 декабря 2008

Одно из решений Oracle:

SELECT id FROM table WHERE id in (7,2,5,9,8)
ORDER BY DECODE(id,7,1,2,2,5,3,9,4,8,5,6);

Это присваивает номер заказа каждому ID. Работает нормально для небольшого набора значений.

0 голосов
/ 25 сентября 2008

Здесь вы быстро получаете ответы, не так ли ...

Причина, по которой я спрашиваю это, заключается в том, что это единственный способ избежать сложного многомерного массива. Я не говорю, что это будет трудно отсортировать, но если бы существовал более простой способ сделать это с прямым SQL, почему бы и нет.

0 голосов
/ 25 сентября 2008

Хм, не совсем. Самое близкое, что вы можете получить, это:

SELECT * FROM table WHERE id IN (3, 2, 1, 4) ORDER BY id=4, id=1, id=2, id=3

Но вы, вероятно, не хотите этого:)

Трудно дать вам какой-либо более конкретный совет без дополнительной информации о том, что в таблицах.

0 голосов
/ 25 сентября 2008

Лучшее, о чем я могу думать, это добавление второго столбца orderColumn:

7 1
2 2
5 3
9 4 
8 5

А затем просто сделайте ORDER BY orderColumn

0 голосов
/ 25 сентября 2008

Это хаки (и, вероятно, медленно), но вы можете получить эффект с помощью UNION ALL:

SELECT id FROM table WHERE id = 7
UNION ALL SELECT id FROM table WHERE id = 2
UNION ALL SELECT id FROM table WHERE id = 5
UNION ALL SELECT id FROM table WHERE id = 9
UNION ALL SELECT id FROM table WHERE id = 8;

Редактировать: Другие люди упоминали функцию find_in_set, которая задокументирована здесь .

0 голосов
/ 25 сентября 2008

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

0 голосов
/ 25 сентября 2008

Это работает в Oracle. Можете ли вы сделать что-то подобное в MySql?

SELECT ID_FIELD
FROM SOME_TABLE
WHERE ID_FIELD IN(11,10,14,12,13)
ORDER BY
  CASE WHEN ID_FIELD = 11 THEN 0
       WHEN ID_FIELD = 10 THEN 1
       WHEN ID_FIELD = 14 THEN 2
       WHEN ID_FIELD = 12 THEN 3
       WHEN ID_FIELD = 13 THEN 4
  END
...