2010-03-16 7 views
0

Je viens suis tombé sur cette requête de base de données et se demander ce does..Please de requête clarifier exactement ce que ..besoin des explications pour cette requête MySQL

select * from tablename order by priority='High' DESC, priority='Medium' DESC, priority='Low" DESC; 
+0

Est-ce que ma description détaillée m'a aidé? –

Répondre

0

On dirait que ça va commander la priorité élevée, moyenne puis basse .

Parce que si l'ordre par la clause était juste priorité DESC alors il le ferait alphabétique, ce qui donnerait

moyen faible élevé

0

Il énumère essentiellement tous les champs de la table « tablename » et ordonné par priorité Haute, Moyenne, Basse. So High apparaît d'abord dans la liste, puis moyen, et puis finalement faible

-à-dire

* High 
* High 
* High 
* Medium 
* Medium 
* Low 

Où * est le reste des champs de la table

0

D'autres ont déjà expliqué ce que id ne (Haut vient en premier, puis Moyen, puis Bas). Je vais juste ajouter quelques mots sur POURQUOI qui est ainsi.

La raison en est que le résultat d'une comparaison dans MySQL est un entier - 1 si c'est vrai, 0 s'il est faux. Et vous pouvez trier par entiers, donc cette construction fonctionne. Je ne suis pas sûr que cela volerait sur d'autres SGBDR cependant.

Ajouté: OK, une explication plus détaillée. Tout d'abord, commençons par le fonctionnement de ORDER BY.

ORDER BY prend une liste d'arguments séparés par des virgules qu'elle évalue pour chaque ligne. Ensuite, il trie par ces arguments. Ainsi, par exemple, nous allons prendre l'exemple classique:

SELECT * from MyTable ORDER BY a, b, c desc 

Qu'est-ce ORDER BY fait dans ce cas, est qu'il obtient le résultat complet mis en mémoire quelque part, et pour chaque ligne, il évalue les valeurs de a, b et c. Ensuite, il trie tout en utilisant un algorithme de tri standard (tel que quicksort). Lorsqu'il a besoin de comparer deux lignes pour déterminer laquelle vient en premier, il compare d'abord les valeurs de a pour les deux lignes; si ceux-ci sont égaux, il compare les valeurs de b; et, si ceux-ci sont égaux aussi, il compare finalement les valeurs de c. Assez simple, non? C'est ce que tu ferais aussi. OK, considérons maintenant quelque chose de plus compliqué. Prenez ceci:

SELECT * from MyTable ORDER BY a+b, c-d 

Ceci est fondamentalement la même chose, sauf que, avant tout le tri, ORDER BY prend toutes les lignes et calcule a+b et c-d et stocke les résultats dans les colonnes invisibles qu'il crée juste pour le tri. Ensuite, il compare simplement ces valeurs comme dans le cas précédent. Essentiellement, ORDER BY crée une table comme ceci:

+-------------------+-----+-----+-----+-----+-------+-------+ 
| Some columns here | A | B | C | D | A+B | C-D | 
+-------------------+-----+-----+-----+-----+-------+-------+ 
|     | 1 | 2 | 3 | 4 | 3 | -1 | 
|     | 8 | 7 | 6 | 5 | 15 | 1 | 
|     | ... | ... | ... | ... | ... | ... | 
+-------------------+-----+-----+-----+-----+-------+-------+ 

Et trie tout cela par les deux dernières colonnes, qu'il se défausse après. Vous ne les voyez même pas votre ensemble de résultats.

OK, quelque chose encore plus étrange:

SELECT * from MyTable ORDER BY CASE WHEN a=b THEN c ELSE D END 

Encore une fois - avant le tri est effectué, ORDER BY passera par chaque ligne, calculer la valeur de l'expression CASE WHEN a=b THEN c ELSE D END et le stocker dans une colonne invisible. Cette expression évaluera toujours à une certaine valeur, ou vous obtenez une exception. Ensuite, il trie juste par cette colonne qui contient des valeurs simples, pas seulement une formule de fantaisie.

+-------------------+-----+-----+-----+-----+-----------------------------------+ 
| Some columns here | A | B | C | D | CASE WHEN a=b THEN c ELSE D END | 
+-------------------+-----+-----+-----+-----+-----------------------------------+ 
|     | 1 | 2 | 3 | 4 |     4     | 
|     | 3 | 3 | 6 | 5 |     6     | 
|     | ... | ... | ... | ... |    ...    | 
+-------------------+-----+-----+-----+-----+-----------------------------------+ 

Espérons que vous êtes maintenant à l'aise avec cette partie. Sinon, relisez-le ou demandez d'autres exemples.

La prochaine chose est les expressions booléennes. Ou plutôt le type booléen, qui pour MySQL est un entier. En d'autres termes SELECT 2>3 renverra 0 et SELECT 2<3 renverra 1. C'est juste. Le type booléen est un entier. Et vous pouvez faire des choses entières avec ça aussi. Comme SELECT (2<3)+5 retournera 6.

OK, maintenant mettons tout cela ensemble. Prenons votre requête:

select * from tablename order by priority='High' DESC, priority='Medium' DESC, priority='Low" DESC; 

Ce qui se passe est que ORDER BY voit une table comme ceci:

+-------------------+----------+-----------------+-------------------+----------------+ 
| Some columns here | priority | priority='High' | priority='Medium' | priority='Low' | 
+-------------------+----------+-----------------+-------------------+----------------+ 
|     | Low  |  0  |   0   |  1  | 
|     | High  |  1  |   0   |  0  | 
|     | Medium |  0  |   1   |  0  | 
|     | Low  |  0  |   0   |  1  | 
|     | High  |  1  |   0   |  0  | 
|     | Low  |  0  |   0   |  1  | 
|     | Medium |  0  |   1   |  0  | 
|     | High  |  1  |   0   |  0  | 
|     | Medium |  0  |   1   |  0  | 
|     | Low  |  0  |   0   |  1  | 
+-------------------+----------+-----------------+-------------------+----------------+ 

Et il trie par les trois dernières colonnes invisble qui sont mis au rebut plus tard.

Cela a-t-il un sens maintenant? En réalité, bien sûr, il n'y a pas de colonnes invisibles et le tout est rendu beaucoup plus difficile pour obtenir une bonne vitesse, en utilisant si possible des index et d'autres choses, mais il est beaucoup plus facile de comprendre le processus de cette façon. Ce n'est pas faux non plus.)

+0

Sur une note de côté, j'ai trouvé un bug intéressant il y a quelques jours qui devait faire face à la même construction. Un développeur a écrit 'WHERE colA = 15 = colB' en essayant de vérifier que les deux colonnes étaient égales à 15. Cet effet s'est retourné parce que' colA = 15' était égal à 1 et la comparaison résultante était équivalente à 'WHERE colA = 15 ET colB = 1' . Ce qui est marrant, c'est que ce code a été produit pendant ** ans **, la ligne en question a été exécutée au moins une fois par jour, mais le bug est apparu la semaine dernière. Parlez de données chanceuses! –

+0

merci pour cela, mais je ne suis pas encore à l'aise avec la requête .. – Sachindra

Questions connexes