Kolejność MySQL według określonych wartości ID

96

Czy możliwe jest sortowanie w mysql według „kolejności według” przy użyciu predefiniowanego zestawu wartości kolumn (ID), takich jak: order by (ID = 1,5,4,3), aby uzyskać rekord 1, 5, 4, 3 w tym rozkazać?

UPDATE: O nadużywaniu mysql ;-) Muszę wyjaśnić, dlaczego tego potrzebuję ...

Chcę, aby moje rekordy zmieniały się losowo co 5 minut. Mam zadanie crona, aby zrobić tabelę aktualizacji, aby umieścić w niej inny, losowy porządek sortowania. Jest tylko jeden problem! PAGINACJA. Będę miał gościa, który wejdzie na moją stronę i dam mu pierwsze 20 wyników. Poczeka 6 minut i przejdzie do strony 2, a wyniki będą błędne, ponieważ kolejność sortowania już się zmieniła.

Pomyślałem więc, że jeśli przychodzi do mojej witryny, umieszczam wszystkie identyfikatory w sesji, a kiedy jest na stronie 2, otrzymuje prawidłowe rekordy, nawet jeśli sortowanie już się zmieniło.

Czy jest inny, lepszy sposób, aby to zrobić?

Jerry2
źródło
Pytasz, czy istnieje sposób, w jaki mysql może zamawiać w dowolnej kolejności?
stefgosselin
1
Wygląda na to, że albo twój model danych jest uszkodzony / niekompletny ( skąd pochodzi ta kolejność?), Albo alternatywnie nadużywasz MySQL.
derobert

Odpowiedzi:

204

Możesz użyć funkcji ORDER BY i FIELD. Zobacz http://lists.mysql.com/mysql/209784

SELECT * FROM table ORDER BY FIELD(ID,1,5,4,3)

Używa funkcji Field () , która "Zwraca indeks (pozycję) str na liście str1, str2, str3, .... Zwraca 0 jeśli str nie zostanie znaleziony" zgodnie z dokumentacją. Czyli w rzeczywistości sortujesz wynik według wartości zwracanej przez tę funkcję, która jest indeksem wartości pola w danym zestawie.

Manjula
źródło
Nie wydaje mi się, aby to działało bez użycia: WHERE ID IN (1,5,4,3)
TV-C-15
1
jak użyłbyś tego z wartościami Brak?
Nono London
30

Powinieneś być w stanie użyć CASEdo tego:

ORDER BY CASE id
  WHEN 1 THEN 1
  WHEN 5 THEN 2
  WHEN 4 THEN 3
  WHEN 3 THEN 4
  ELSE 5
END
NPE
źródło
18

W oficjalnej dokumentacji mysql dotyczącej ORDER BY ktoś napisał, że możesz użyć FIELDw tej sprawie, na przykład:

SELECT * FROM table ORDER BY FIELD(id,1,5,4,3)

To niesprawdzony kod, który w teorii powinien działać.

Jan Dragsbaek
źródło
7
SELECT * FROM table ORDER BY id='8' DESC, id='5' DESC, id='4' DESC, id='3' DESC

Gdybym miał na przykład 10 rejestrów, w ten sposób ID 1, 5, 4 i 3 pojawią się jako pierwsze, a pozostałe rejestry pojawią się jako następne.

Wystawa normalna 1 2 3 4 5 6 7 8 9 10

W ten sposób

8 5 4 3 1 2 6 7 9 10

Bruno Mangini Alves
źródło
Ok Dzięki za radę
Bruno Mangini Alves
6

Jest inny sposób rozwiązania tego problemu. Dodaj oddzielną tabelę, coś takiego:

CREATE TABLE `new_order` (
  `my_order` BIGINT(20) UNSIGNED NOT NULL,
  `my_number` BIGINT(20) NOT NULL,
  PRIMARY KEY (`my_order`),
  UNIQUE KEY `my_number` (`my_number`)
) ENGINE=INNODB;

Ta tabela będzie teraz używana do definiowania własnego mechanizmu zamówień.

Dodaj tam swoje wartości:

my_order | my_number
---------+----------
       1 |         1
       2 |         5
       3 |         4
       4 |         3

... a następnie zmodyfikuj instrukcję SQL, dołączając do nowej tabeli.

SELECT *
FROM your_table AS T1
INNER JOIN new_order AS T2 on T1.id = T2.my_number
WHERE ....whatever...
ORDER BY T2.my_order; 

To rozwiązanie jest nieco bardziej złożone niż inne rozwiązania, ale korzystając z niego nie musisz zmieniać swojego SELECToświadczenia za każdym razem, gdy zmienią się Twoje kryteria zamówienia - wystarczy zmienić dane w tabeli zamówień.

Bjoern
źródło
1

Jeśli chcesz najpierw zamówić pojedynczy identyfikator w wyniku, użyj id.

select id,name 
from products
order by case when id=5 then -1 else id end

Jeśli chcesz zacząć od sekwencji wielu identyfikatorów, określ kolekcję, podobnie jak w przypadku INinstrukcji.

select id,name 
from products
order by case when id in (30,20,10) then -1 else id end,id
Rajesh Kharatmol
źródło
Dodaj więcej opisu
Mathews Sunny,
jeśli chcesz użyć kolejności według tylko dla jednego identyfikatora, użyj pierwszego zapytania, a jeśli chcesz dla wielu identyfikatorów, użyj drugiego zapytania
Rajesh Kharatmol
0

Jeśli chcesz zamówić pojedynczy identyfikator jako ostatni w wyniku, użyj kolejności według przypadku. (Np .: chcesz, aby opcja „inne” znajdowała się na liście ostatnich miast, a wszystkie miasta były wyświetlane w porządku alfabetycznym).

select id,city 
from city
order by case 
when id = 2 then city else -1 
end, city ASC

Gdybym na przykład miał 5 miast, chciałbym pokazać miasto w porządku alfabetycznym z opcją „inne” wyświetlaną jako ostatnią na liście rozwijanej, wtedy możemy użyć tego zapytania. zobacz przykład inne są wyświetlane w mojej tabeli pod drugim identyfikatorem (id: 2), więc używam „when id = 2” w powyższym zapytaniu.

rekord w tabeli DB:

Bangalore - id:1
Other     - id:2
Mumbai    - id:3
Pune      - id:4
Ambala    - id:5

moje wyjście:

Ambala  
Bangalore  
Mumbai  
Pune
Other
Preeti
źródło
2
Spróbuj dodać jakieś wyjaśnienie do swojego kodu, dzięki temu twoja odpowiedź będzie bardziej jasna i zrozumiała. Przeczytaj stackoverflow.com/help/how-to-answer
32cupo
jeśli chcesz użyć kolejności według tylko dla jednego identyfikatora (np. chcesz, aby opcja „inne” na liście ostatnich miast była wyświetlana w kolejności alfabetycznej), więc możesz użyć tego zapytania. to działa dla mnie.
Preeti
-1
SELECT * FROM TABLE ORDER BY (columnname,1,2) ASC OR DESC
Hisham shahid
źródło
2
Czy możesz to dalej wyjaśnić? To wygląda podobnie do zaakceptowanej odpowiedzi, ale nie sądzę, że ASC OR DESCjest to właściwa składnia
Nico Haase
@NicoHaase różnica między ASC i DESC polega na tym, że jeśli użyjesz asc, wtedy identyfikatory używane w funkcji field zostaną zakończone, a jeśli użyjesz DESC, to identyfikatory w funkcji field będą pierwsze
Hisham shahid
@NicoHaase możesz użyć ASC lub DESC z zapytaniem zgodnym z wymaganiami
Hisham shahid
Nie możesz więc używać obu w jednym zapytaniu. Nico, jak sądzę, sugerował, że poprawiłaś składnię swojej odpowiedzi. Jestem prawie pewien, że wie, co właściwie oznaczają ASD i DESC :)
RiggsFolly
To nie ma sensu i na pewno nie zadziała. Musisz skorzystać z FIELDfunkcji, która jest identyczna z akceptowaną odpowiedzią sprzed 8 lat.
hackel