Ordine Mysql per valori ID specifici


95

È possibile ordinare in mysql per "ordina per" utilizzando un set predefinito di valori di colonna (ID) come: ordina per (ID = 1,5,4,3) in modo da ottenere il record 1, 5, 4, 3 in quello ordine fuori?

AGGIORNAMENTO: sull'abuso di mysql ;-) Devo spiegare perché ho bisogno di questo ...

Voglio che i miei record cambino ordinamento in modo casuale ogni 5 minuti. Ho un'attività cron per eseguire la tabella di aggiornamento per inserire un ordinamento casuale diverso. C'è solo un problema! PAGINAZIONE. Avrò un visitatore che viene alla mia pagina e gli darò i primi 20 risultati. Aspetterà 6 minuti e andrà a pagina 2 e avrà risultati errati poiché l'ordinamento era già cambiato.

Quindi ho pensato che se arriva sul mio sito metto tutti gli ID a una sessione e quando è a pagina 2 ottiene i record corretti anche se l'ordinamento è già cambiato.

C'è un altro modo migliore per farlo?


Stai chiedendo se esiste un modo in cui mysql può ordinare senza un ordine particolare?
stefgosselin

1
Sembra che il tuo modello di dati sia rotto / incompleto (da dove viene questo ordine?) O in alternativa stai abusando di MySQL.
derobert

Risposte:


202

È possibile utilizzare la funzione ORDER BY e FIELD. Vedi http://lists.mysql.com/mysql/209784

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

Utilizza la funzione Field () , che "Restituisce l'indice (posizione) di str nell'elenco str1, str2, str3, ... Restituisce 0 se str non viene trovato" secondo la documentazione. Quindi in realtà si ordina il risultato impostato in base al valore di ritorno di questa funzione che è l'indice del valore del campo nell'insieme dato.


Non riesco a farlo funzionare senza usare anche: WHERE ID IN (1,5,4,3)
TV-C-15

come useresti questo con Nessuno valori?
Nono London,

30

Dovresti essere in grado di utilizzare CASEper questo:

ORDER BY CASE id
  WHEN 1 THEN 1
  WHEN 5 THEN 2
  WHEN 4 THEN 3
  WHEN 3 THEN 4
  ELSE 5
END

18

Sulla documentazione ufficiale per mysql su ORDER BY , qualcuno ha pubblicato che puoi usare FIELDper questo argomento, in questo modo:

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

Questo è un codice non testato che in teoria dovrebbe funzionare.


7
SELECT * FROM table ORDER BY id='8' DESC, id='5' DESC, id='4' DESC, id='3' DESC

Ad esempio, se avessi 10 registri, in questo modo appariranno per primi gli ID 1, 5, 4 e 3, successivamente verranno visualizzati gli altri registri.

Mostra normale 1 2 3 4 5 6 7 8 9 10

In questo modo

8 5 4 3 1 2 6 7 9 10


Ok Grazie del consiglio
Bruno Mangini Alves

6

C'è un altro modo per risolvere questo problema. Aggiungi una tabella separata, simile a questa:

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;

Questa tabella verrà ora utilizzata per definire il proprio meccanismo di ordinazione.

Aggiungi i tuoi valori lì:

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

... e quindi modifica la tua istruzione SQL mentre ti unisci a questa nuova tabella.

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; 

Questa soluzione è leggermente più complessa di altre soluzioni, ma utilizzando questa non è necessario modificare la propria SELECTdichiarazione ogni volta che cambiano i criteri del proprio ordine - modificare semplicemente i dati nella tabella dell'ordine.


0
SELECT * FROM TABLE ORDER BY (columnname,1,2) ASC OR DESC

2
Puoi spiegarlo ulteriormente? Sembra simile alla risposta accettata, ma non credo che ASC OR DESCsia la sintassi corretta
Nico Haase

@NicoHaase la differenza tra ASC e DESC è che se usi ASC, gli ID che usi nella funzione di campo arriveranno alla fine e se usi DESC, gli ID nella funzione di campo verranno per primi
Hisham shahid

@NicoHaase puoi usare ASC o DESC con la query che accede al requisito
Hisham shahid

Quindi non puoi usare entrambi in una query. Nico credo ti abbia suggerito di rendere sintatticamente corretta la tua risposta. Sono abbastanza sicuro che abbia familiarità con ciò che realmente significano ASD e DESC :)
RiggsFolly

0

Se devi prima ordinare un singolo ID nel risultato, usa l'id.

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

Se devi iniziare con una sequenza di più ID, specifica una raccolta, simile a quella che useresti con INun'istruzione.

select id,name 
from products
order by case when id in (30,20,10) then -1 else id end,id

Aggiungi qualche altra descrizione
Mathews Sunny

se si desidera utilizzare l'ordine per un solo ID, utilizzare la prima query e se si desidera più ID utilizzare la seconda query
Rajesh Kharatmol

0

Se vuoi ordinare un singolo ID per ultimo nel risultato, usa l'ordine per caso. (Ad esempio: si desidera che l'opzione "altro" nell'ultima lista di città venga visualizzata in ordine alfabetico.)

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

Se avessi 5 città, ad esempio, voglio mostrare la città in ordine alfabetico con l'opzione "altro" visualizzata per ultima nel menu a discesa, allora possiamo usare questa query. vedi esempio altri stanno mostrando nella mia tabella al secondo id (id: 2) quindi sto usando "quando id = 2" nella query sopra.

registrare nella tabella DB:

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

la mia uscita:

Ambala  
Bangalore  
Mumbai  
Pune
Other

2
Prova ad aggiungere qualche spiegazione al tuo codice, renderà la tua risposta più chiara e comprensibile. Si prega di leggere stackoverflow.com/help/how-to-answer
32cupo

se vuoi usare order by per un solo ID (ad esempio: vuoi l'opzione "altro" nell'ultimo e l'elenco di tutte le città viene mostrato in ordine alfabetico.) quindi puoi usare questa query. sta funzionando per me.
Preeti
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.