Ordre MySQL par valeurs d'ID spécifiques

95

Est-il possible de trier dans mysql par "ordre par" en utilisant un ensemble prédéfini de valeurs de colonne (ID) comme: ordre par (ID = 1,5,4,3) afin d'obtenir l'enregistrement 1, 5, 4, 3 en cela commander?

MISE À JOUR: À propos de l'utilisation abusive de mysql ;-) Je dois expliquer pourquoi j'ai besoin de ça ...

Je veux que mes enregistrements changent de manière aléatoire toutes les 5 minutes. J'ai une tâche cron pour faire la table de mise à jour pour y mettre un ordre de tri différent et aléatoire. Il n'y a qu'un seul problème! PAGINATION. J'aurai un visiteur qui vient sur ma page et je lui donne les 20 premiers résultats. Il attendra 6 minutes et ira à la page 2 et il aura des résultats erronés car l'ordre de tri a déjà changé.

J'ai donc pensé que s'il venait sur mon site, je mettrais tous les identifiants dans une session et quand il est à la page 2, il obtient les bons enregistrements même si le tri a déjà changé.

Y a-t-il un autre moyen, mieux, de faire cela?

Jerry2
la source
Êtes-vous en train de demander s'il existe un moyen pour mysql de commander sans ordre particulier?
stefgosselin
1
Il semble que votre modèle de données soit cassé / incomplet (d' vient cet ordre?) Ou que vous abusez de MySQL.
derobert

Réponses:

202

Vous pouvez utiliser la fonction ORDER BY et FIELD. Voir http://lists.mysql.com/mysql/209784

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

Il utilise la fonction Field () , qui "renvoie l'index (position) de str dans la liste str1, str2, str3, .... Renvoie 0 si str n'est pas trouvé" selon la documentation. Donc, en fait, vous triez l'ensemble de résultats par la valeur de retour de cette fonction qui est l'index de la valeur du champ dans l'ensemble donné.

Manjula
la source
Je n'arrive pas à faire fonctionner cela sans utiliser également: WHERE ID IN (1,5,4,3)
TV-C-15
comment utiliseriez-vous cela avec les valeurs None?
Nono London le
30

Vous devriez pouvoir utiliser CASEpour cela:

ORDER BY CASE id
  WHEN 1 THEN 1
  WHEN 5 THEN 2
  WHEN 4 THEN 3
  WHEN 3 THEN 4
  ELSE 5
END
NPE
la source
18

Sur la documentation officielle de mysql sur ORDER BY , quelqu'un a posté que vous pouvez utiliser FIELDpour cette question, comme ceci:

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

Il s'agit d'un code non testé qui, en théorie, devrait fonctionner.

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

Si j'avais 10 registres par exemple, de cette façon les ID 1, 5, 4 et 3 apparaîtront en premier, les autres registres apparaîtront ensuite.

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

Avec cette façon

8 5 4 3 1 2 6 7 9 10

Bruno Mangini Alves
la source
Ok Merci pour les conseils
Bruno Mangini Alves
6

Il existe une autre façon de résoudre ce problème. Ajoutez une table séparée, quelque chose comme ceci:

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;

Ce tableau va maintenant être utilisé pour définir votre propre mécanisme de commande.

Ajoutez vos valeurs ici:

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

... puis modifiez votre instruction SQL en rejoignant cette nouvelle table.

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; 

Cette solution est légèrement plus complexe que les autres solutions, mais en l'utilisant, vous n'avez pas à changer votre SELECTdéclaration chaque fois que vos critères de commande changent - il suffit de changer les données dans la table de commande.

Bjoern
la source
0
SELECT * FROM TABLE ORDER BY (columnname,1,2) ASC OR DESC
Hisham shahid
la source
2
Pouvez-vous expliquer cela davantage? Cela ressemble à la réponse acceptée, mais je ne pense pas que la ASC OR DESCsyntaxe soit correcte
Nico Haase
@NicoHaase la différence entre ASC et DESC est que si vous utilisez asc, les identifiants que vous utilisez dans la fonction de champ viendront à la fin et si vous utilisez DESC, les identifiants dans la fonction de champ viendront en premier
Hisham shahid
@NicoHaase, vous pouvez utiliser ASC ou DESC avec la requête soit selon l'exigence
Hisham shahid
Vous ne pouvez donc pas utiliser les deux dans une seule requête. Je pense que Nico vous a suggéré de rendre votre réponse syntaxiquement correcte. Je suis presque sûr qu'il connaît ce que signifient réellement ASD et DESC :)
RiggsFolly
0

Si vous devez d'abord commander un identifiant unique dans le résultat, utilisez l'identifiant.

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

Si vous devez commencer par une séquence de plusieurs identifiants, spécifiez une collection, similaire à celle que vous utiliseriez avec une INinstruction.

select id,name 
from products
order by case when id in (30,20,10) then -1 else id end,id
Rajesh Kharatmol
la source
Ajouter un peu plus de description
Mathews Sunny
si vous souhaitez utiliser order by pour un seul identifiant, utilisez la 1ère requête et si vous voulez plusieurs identifiants, utilisez la 2ème requête
Rajesh Kharatmol
0

Si vous souhaitez commander un seul identifiant en dernier dans le résultat, utilisez l'ordre par cas. (Par exemple: vous voulez l'option "autre" dans la dernière liste de villes et toutes les villes sont affichées par ordre alphabétique.)

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

Si j'avais 5 villes par exemple, je veux afficher la ville par ordre alphabétique avec l'option "autre" affichée en dernier dans la liste déroulante, nous pouvons utiliser cette requête. voir l'exemple que d'autres affichent dans ma table au deuxième id (id: 2) donc j'utilise "quand id = 2" dans la requête ci-dessus.

enregistrement dans la table DB:

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

ma sortie:

Ambala  
Bangalore  
Mumbai  
Pune
Other
Preeti
la source
2
Essayez d'ajouter une explication à votre code, cela rendra votre réponse plus claire et compréhensible. Veuillez lire stackoverflow.com/help/how-to-answer
32cupo
si vous voulez utiliser l'ordre par pour un seul identifiant (par exemple: vous voulez l'option "autre" dans la dernière et toutes les listes de villes par ordre alphabétique.) vous pouvez donc utiliser cette requête. ça marche pour moi.
Preeti