web-dev-qa-db-fra.com

Ordre Mysql par valeurs d'ID spécifiques

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

PDATE: À propos de l'abus de mysql ;-) Je dois expliquer pourquoi j'ai besoin de ça ...

Je veux que mes enregistrements changent de façon aléatoire toutes les 5 minutes. J'ai une tâche périodique à effectuer dans la table de mise à jour pour y placer un ordre de tri aléatoire différent. Il n'y a qu'un problème! PAGINATION. Je vais avoir un visiteur qui vient à ma page et je lui donne 20 premiers résultats. Il attendra 6 minutes et passera à la page 2 et il obtiendra 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 mettais toutes les cartes d'identité en session et quand il se trouvait à la page 2, il récupérait les bons enregistrements même si le tri avait déjà changé.

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

79
Jerry2

Vous pouvez utiliser les fonctions 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 "Retourne l'index (position) de str dans la liste str1, str2, str3, .... Renvoie 0 si str n'est pas trouvé" selon la documentation. Donc, en réalité, vous triez le jeu de résultats en fonction de la valeur de retour de cette fonction, qui correspond à l'index de la valeur de champ dans le jeu donné.

162
Manjula

Vous devriez pouvoir utiliser CASE pour cela:

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

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

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

C'est un code non testé qui devrait théoriquement fonctionner.

15
Jan Dragsbaek

Il existe un autre moyen de résoudre ce problème. Ajouter 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 d’autres solutions, mais elle vous évite de modifier votre instruction SELECT- à chaque modification de vos critères de commande; il vous suffit de modifier les données de la table des commandes.

5
Bjoern

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

Si j'avais 10 registres par exemple, 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

De cette façon

8 5 4 3 1 2 6 7 9 10

3
SELECT * FROM TABLE ORDER BY (columnname,1,2) ASC OR DESC
1
Hisham shahid