Ordre selection tables
Posté : 08 janv. 2011, 02:16
Bonjour à tous.
La question se trouve à la fin. J'explique toutefois les manipulations effectuées histoire que d'autres critiques ou d'autres idées puissent être postées (sans s'arrêter à la stricte question qui peut vite sortir du contexte).
J'avais déjà fait la malheureuse expérience d'un SELECT FROM a,b,c où mysql effectuait une boucle dans l'odre c,b,a. un peu comme un foreach(c) { foreach (b) { foreach (a) { }}}
Lors d'une jointure, la syntaxe :
SELECT A.id, A.descr, B.name FROM `SUIVI_state_cat` B INNER JOIN SUIVI_state A ON B.id = A.category
Me mets les choses comme "il faut", enfin, par rapport à leur ordre dans la table. Il commence donc bien par les catégories avant les "state" (donc là, de gauche à droite). Si on inverse l'ordre des deux tables : rien ne change. On a donc, comme la documentation le dit, MySQL qui gère sa petite sauce.
Maintenant, je veux que il trie les catégories en fonction d'un champ nommé "order", et les state d'un champs nommé de la même façon.
Evidemment, comme on pouvait s'y attendre si on y réfléchit un temps soit peu, ça ne va pas si on ne contente de mettre après la requête ci dessus un ORDER BY ... Car, c'est bien dans l'ordre, mais si deux catégories ont le même ordre, leurs states sont mélangés dans ces catégories de même ordre.
Pour illustrer, au lieu d'avoir
CAT xx - State 1
CAT xx - State 2
CAT yy - State 1
CAT yy - State 2
On a :
CAT xx - State 1
CAT yy - State 1
CAT xx - State 2
CAT yy - State 2
Et mon but, c'est d'avoir un résultat mySQL prêt à être exploité par Php en le "parsant", sans devoir re-mettre dans le bon ordre. Donc il faut absolument que les State d'une même catégorie soient groupées.
Donc, j'essaie
SELECT A.id, A.descr, B.name FROM (SELECT * FROM `SUIVI_state_cat` ORDER BY `order` ASC) B INNER JOIN
(SELECT * FROM `SUIVI_state` ORDER BY `order` ASC) A
ON B.id = A.category
Ce qui est parfait, en soit. Sauf que ... hébé ... Ca ne marche pas. MySQL décide de commencer par la table des state au lieu des catégories. C'est donc effectivement dans l'ordre, mais pas du tout celui que je voulais. Il me faut donc définir moi-même l'ordre de selection des tables. Au fond, là je lui demande rien de plus que d'effectuer des boucles ...
SELECT STRAIGHT_JOIN A.id, A.descr, B.name FROM (SELECT * FROM `SUIVI_state_cat` ORDER BY `order` ASC) B INNER JOIN
(SELECT * FROM `SUIVI_state` ORDER BY `order` ASC) A
ON B.id = A.category
Paf ... d'après la doc, ce sont les tables les plus à gauche qui sont lues d'abord. Ben ... aucune différence. Par contre, si j'inverse
SELECT STRAIGHT_JOIN A.id, A.descr, B.name FROM (SELECT * FROM `SUIVI_state` ORDER BY `order` ASC) A INNER JOIN
(SELECT * FROM `SUIVI_state_cat` ORDER BY `order` ASC) B
ON B.id = A.category
Magie ! C'est bien ce que je voulais !
Donc, je voudrais être sûr ... quand on dit que Mysql lit de gauche à droite (dans ce cas là, mais ça doit être écrit ailleurs ...), ils sous-entendent que ce sont des arabes qui l'ont fait et que MySQL lit de droit à gauche ?? Sérieusement, ai-je loupé quelque chose ou c'est bien l'ordre droite->gauche ??
Bien cordialement,
La question se trouve à la fin. J'explique toutefois les manipulations effectuées histoire que d'autres critiques ou d'autres idées puissent être postées (sans s'arrêter à la stricte question qui peut vite sortir du contexte).
J'avais déjà fait la malheureuse expérience d'un SELECT FROM a,b,c où mysql effectuait une boucle dans l'odre c,b,a. un peu comme un foreach(c) { foreach (b) { foreach (a) { }}}
Lors d'une jointure, la syntaxe :
SELECT A.id, A.descr, B.name FROM `SUIVI_state_cat` B INNER JOIN SUIVI_state A ON B.id = A.category
Me mets les choses comme "il faut", enfin, par rapport à leur ordre dans la table. Il commence donc bien par les catégories avant les "state" (donc là, de gauche à droite). Si on inverse l'ordre des deux tables : rien ne change. On a donc, comme la documentation le dit, MySQL qui gère sa petite sauce.
Maintenant, je veux que il trie les catégories en fonction d'un champ nommé "order", et les state d'un champs nommé de la même façon.
Evidemment, comme on pouvait s'y attendre si on y réfléchit un temps soit peu, ça ne va pas si on ne contente de mettre après la requête ci dessus un ORDER BY ... Car, c'est bien dans l'ordre, mais si deux catégories ont le même ordre, leurs states sont mélangés dans ces catégories de même ordre.
Pour illustrer, au lieu d'avoir
CAT xx - State 1
CAT xx - State 2
CAT yy - State 1
CAT yy - State 2
On a :
CAT xx - State 1
CAT yy - State 1
CAT xx - State 2
CAT yy - State 2
Et mon but, c'est d'avoir un résultat mySQL prêt à être exploité par Php en le "parsant", sans devoir re-mettre dans le bon ordre. Donc il faut absolument que les State d'une même catégorie soient groupées.
Donc, j'essaie
SELECT A.id, A.descr, B.name FROM (SELECT * FROM `SUIVI_state_cat` ORDER BY `order` ASC) B INNER JOIN
(SELECT * FROM `SUIVI_state` ORDER BY `order` ASC) A
ON B.id = A.category
Ce qui est parfait, en soit. Sauf que ... hébé ... Ca ne marche pas. MySQL décide de commencer par la table des state au lieu des catégories. C'est donc effectivement dans l'ordre, mais pas du tout celui que je voulais. Il me faut donc définir moi-même l'ordre de selection des tables. Au fond, là je lui demande rien de plus que d'effectuer des boucles ...
SELECT STRAIGHT_JOIN A.id, A.descr, B.name FROM (SELECT * FROM `SUIVI_state_cat` ORDER BY `order` ASC) B INNER JOIN
(SELECT * FROM `SUIVI_state` ORDER BY `order` ASC) A
ON B.id = A.category
Paf ... d'après la doc, ce sont les tables les plus à gauche qui sont lues d'abord. Ben ... aucune différence. Par contre, si j'inverse
SELECT STRAIGHT_JOIN A.id, A.descr, B.name FROM (SELECT * FROM `SUIVI_state` ORDER BY `order` ASC) A INNER JOIN
(SELECT * FROM `SUIVI_state_cat` ORDER BY `order` ASC) B
ON B.id = A.category
Magie ! C'est bien ce que je voulais !
Donc, je voudrais être sûr ... quand on dit que Mysql lit de gauche à droite (dans ce cas là, mais ça doit être écrit ailleurs ...), ils sous-entendent que ce sont des arabes qui l'ont fait et que MySQL lit de droit à gauche ?? Sérieusement, ai-je loupé quelque chose ou c'est bien l'ordre droite->gauche ??
Bien cordialement,