MySQL - ЗАМОВЛЕННЯ ЗА значеннями в межах IN ()


107

Я сподіваюся сортувати елементи, що повертаються в наступному запиті, у порядку, який вони вводять у функцію IN () .

ВХОД:

SELECT id, name FROM mytable WHERE name IN ('B', 'A', 'D', 'E', 'C');

ВИХІД:

|   id   |   name  |
^--------^---------^
|   5    |   B     |
|   6    |   B     |
|   1    |   D     |
|   15   |   E     |
|   17   |   E     |
|   9    |   C     |
|   18   |   C     |

Якісь ідеї?

Відповіді:


231
SELECT id, name
FROM mytable
WHERE name IN ('B', 'A', 'D', 'E', 'C')
ORDER BY FIELD(name, 'B', 'A', 'D', 'E', 'C')

Функція FIELD повертає позицію першого рядка в решті списку рядків.

Однак набагато краще для продуктивності мати індексований стовпець, який представляє ваш порядок сортування, а потім сортувати за цим стовпцем.


9
@Vladimir - так, це специфічно для MySQL. Питання має тег mysql.
Айман Х'юрі

Відмінна заміна функції «декодування» Oracle після перемикання БД.
Мартін Лін

7
Обережно. Будь-яке невідоме значення властивості (не в списку) матиме перевагу над відомими значеннями, тобто FIELD(letter, 'A', 'C')список спочатку поверне записи з буквою В (припускаючи набір записів зі A | B | Cзначеннями). Щоб цього уникнути, оберніть перелік і використовуйте DESC, тобто FIELD(letter, 'C', 'A') DESC.
Гаджус

Як цього досягти на SQL-сервері.
користувач123456

29

Ще один варіант звідси: http://dev.mysql.com/doc/refman/5.0/en/sorting-rows.html

select * 
from tablename 
order by priority='High' DESC, priority='Medium' DESC, priority='Low" DESC;

Так у вашому випадку (неперевіреним) було б

SELECT id, name
FROM mytable
WHERE name IN ('B', 'A', 'D', 'E', 'C')
ORDER BY name = 'B', name = 'A', name = 'D', name =  'E', name = 'C';

Залежно від того, що ти робиш, я вважав це трохи химерним, але завжди змушував його працювати, трохи граючи з ним.


Це може бути краще, ніж використовувати функцію field () як іншу відповідь, запропоновану, тому що використання field () буде виключати використання індексу, але він має шанс використовувати індекс за допомогою цього методу (не впевнений, наскільки добре він може використовувати індекс), хоча
ʞɔıu


3

Це може допомогти комусь (p_CustomerId передається в SP):

SELECT CompanyAccountId, CompanyName
FROM account
LEFT JOIN customer where CompanyAccountId = customer.AccountId
GROUP BY CompanyAccountId
ORDER BY CASE WHEN CompanyAccountId IN (SELECT AccountId 
                                          FROM customer
                                          WHERE customerid= p_CustomerId) 
                 THEN 0
                 ELSE 1
          END, CompanyName;

Опис: Я хочу показати список облікових записів. Ось я передаю ідентифікатор клієнта в sp. Тепер він перелічить імена облікових записів із обліковими записами, пов’язаними з тим, що клієнти відображаються вгорі, а за іншими в акаунті в алфавітному порядку.


2

Вам потрібен інший стовпець (числовий) у вашій таблиці, в якому ви вказуєте порядок сортування. Пункт IN не працює таким чином.

B - 1
A - 2
D - 3
E - 4
C - 5

2
Бажане замовлення може бути на запит.
Володимир Дюжев

0

просто використовувати

order by INSTR( ',B,C,D,A,' ,  concat(',' , `field`, ',' ) )

уникати подібної ситуації

 INSTR('1,2,3,11' ,`field`) 

закінчується не упорядкованим рядком результатів: 1 і 11 чергуванням

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.