MySQL - wartości ORDER BY w IN ()


107

Mam nadzieję, że posortuję elementy zwrócone w poniższym zapytaniu według kolejności, w jakiej zostały wprowadzone do funkcji IN () .

WEJŚCIE:

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

WYNIK:

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

Jakieś pomysły?

Odpowiedzi:


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

Funkcja FIELD zwraca pozycję pierwszego ciągu na pozostałej liście ciągów.

Jednak znacznie lepszą wydajnością jest posiadanie zindeksowanej kolumny, która reprezentuje porządek sortowania, a następnie sortowanie według tej kolumny.


9
@Vladimir - tak, to jest specyficzne dla MySQL. Pytanie ma tag mysql.
Ayman Hourieh

Świetnie, zamiennik funkcji „dekodowania” Oracle po przełączeniu DB.
Martin Lyne

7
Ostrożny. Każda nieznana wartość właściwości (której nie ma na liście) będzie miała pierwszeństwo przed znanymi wartościami, tj FIELD(letter, 'A', 'C'). Lista najpierw zwróci wpisy z literą B jako pierwszą (przy założeniu zestawu rekordów z A | B | Cwartościami). Aby tego uniknąć, odwróć listę i użyj DESC, tj FIELD(letter, 'C', 'A') DESC.
Gajus

Jak to osiągnąć w SQL Server.
user123456

29

Inna opcja stąd: 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;

Więc w twoim przypadku (niesprawdzone) byłoby

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';

W zależności od tego, co robisz, uznałem to za trochę dziwaczne, ale zawsze działało po odrobinie zabawy.


Może to być lepsze niż użycie funkcji field () jako kolejnej sugerowanej odpowiedzi, ponieważ użycie field () uniemożliwi użycie indeksu, ale ma szansę użyć indeksu za pomocą tej metody (chociaż nie jestem pewien, jak dobrze mógłby użyć indeksu)
ʞɔıu


3

Może to może komuś pomóc (p_CustomerId jest przekazywany w 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;

Opis: Chcę pokazać listę kont. Tutaj przekazuję identyfikator klienta w sp. Teraz wyświetli listę nazw rachunków z kontami połączonymi z tymi klientami, które są wyświetlane u góry, a następnie inne konta w kolejności alfabetycznej.


2

Potrzebujesz kolejnej kolumny (numerycznej) w swojej tabeli, w której określisz porządek sortowania. Klauzula IN nie działa w ten sposób.

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

2
Pożądana kolejność może dotyczyć zapytania.
Vladimir Dyuzhev

0

po prostu użyj

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

unikaj takiej sytuacji

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

zakończy się nieuporządkowanym wierszem wyniku: alternatywa 1 i 11

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.