MySQL UNION imbriquée - SQL/NoSQL - Programmation
Marsh Posté le 05-08-2008 à 16:33:45
C'est quoi l'intérêt de mettre un UNION dans un UNION ? (que veux-tu faire exactement ?)
Marsh Posté le 05-08-2008 à 16:34:59
ReplyMarsh Posté le 05-08-2008 à 16:37:02
josiasseb a écrit : L'intérêt c'est de conserver l'ordre. |
Et si tu mets les UNION les uns en dessous des autres, ca ne conserve pas l'ordre ?
Marsh Posté le 05-08-2008 à 16:42:30
Je veux en fait que sur le "sous-UNION" s'applique le ORDER BY, et pas sur l'ensemble.
Et que s'affiche le 1er SELECT, le 2eme, l'ensemble trouvé par la recherche fulltext, puis le dernier SELECT
Marsh Posté le 05-08-2008 à 16:44:22
1/ vire tes "DISTINCT", le "UNION" fait un distinct implicite (cf. norme SQL92)
2/ si tu veux contrôler l'ordre, c'est pas en bidouillant avec les UNION, qui, à cause du DISTINCT justement, ne garantissent absolument pas l'ordre :
table T1 :
|
Table T2
|
tu fais ça :
Code :
|
Vas-t-il te retourner :
|
ou
|
ou
|
?
t'en sais ABSOLUMENT rien, la norme SQL92 n'impose aucune règle.
chacun des trois résultats suis sa logique : le premier ne conserve que la première occurence de chaque sous-requête, le second ne conserve que les deniers, quand à la dernier, il effectue un tri avant de supprimer les doublons
BREF
Code :
|
si tu veux gérer à la main l'ordre, tu peux ajouter une constante dans un champ bidon dans tes sous-select. par contre, ça va garantir l'unicité des résultats, donc il faudra faire des UNION ALL, qui seront infiniment plus rapide que des UNION classiques
Code :
|
Marsh Posté le 05-08-2008 à 16:45:10
ps : et je sais que ça ne répond pas exactement à ta question. maintenant à toi d'adapter ton problème avec cette piste.
Marsh Posté le 05-08-2008 à 16:51:01
Je veux garder l'ordre mais les DISTINCT aussi.
Affichage du 1er SELECT, du 2eme si différent du 1er, ...
Marsh Posté le 05-08-2008 à 17:05:52
à moins de sortir une mysqlbidouille, tu ne peux pas
le modèle n'est pas une information, tu n'as donc pas à savoir d'où vient une donnée à la sortie d'une requête. c'est un des fondements des SGBD. donc pas d'order possible en fonction de la table, et encore moins "garder la ligne d'une table plutôt que d'une autre"
tu peux toujours t'en sortir en faisant une usine à gaz à grands coups de not in () et en conservant le préfixe comme j'ai indiqué : tu sélectionnes tout select 't1' ori, * from t1 union all select 't2' ori, * from t2 where id not exists (select id from t1) order by ori
m'enfin avec la chiée d'union, si tu fous pas à genoux le serveur, t'auras beaucoup de chance
Marsh Posté le 05-08-2008 à 17:09:27
y'a une solution aussi à base de left outer join à la queue leue leue, et en jouant avec des case when, m'enfin là ça va devenir franchement imbittable (ceci dit, ça devrait être performant)
Marsh Posté le 05-08-2008 à 17:11:54
MB> pas besoin de left à mon avis
Bon ok y'a un scan de toute la table mais je suis pas sur que ça soit moins performant que ces multiples unions.
Code :
|
Marsh Posté le 05-08-2008 à 17:19:40
je pige pas trop, parceque ça fait pas le distinct là
ceci dit, effectivement, je préfère ton écriture par rapport à l'écriture originale (en fait, j'avais même pas lu la requête, je m'étais arrêté à la structure et le order by placé à tord au milieu d'une série de union )
Marsh Posté le 05-08-2008 à 17:33:00
J'ai comme impératif de conserver l'ordre que fournisse les utilisateurs.
Un ordre pas toujours bien éclairé, c'est le pourquoi des DISTINCT, et de certains contrôles au préalable.
En mettant un ORDER BY dans chacun des fulltext, ça fonctionne.
Marsh Posté le 06-08-2008 à 09:24:27
MagicBuzz a écrit : je pige pas trop, parceque ça fait pas le distinct là |
J'avais pas vu le distinct
Mais bon suffit de mettre un "select distinct" du coup
josiasseb a écrit : J'ai comme impératif de conserver l'ordre que fournisse les utilisateurs. |
Nan mais les distinct je comprends vaguement leur utilisation. Par contre faire 4 unions de select qui sont tous sur la même table je comprends moins, même si niveau perf il ne doit pas y avoir de grosse différence.
Marsh Posté le 06-08-2008 à 16:26:18
Je n'ai pas le ORDER BY combiné sur mes deux recherches fulltext mais les performances sont assez bonnes.
Donc, satisfait pour l'instant.
Mais je vais regarder du coté des pistes que vous m'avez donné.
Merci
Marsh Posté le 07-08-2008 à 12:52:42
j'avais un problème similaire va voir ici :
http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
Marsh Posté le 07-08-2008 à 14:18:26
Je suis arrivé à peu prêt à la même conclusion, à savoir enchainer les UNION pour conserver l'ordre de mes requêtes.
Je fais un ORDER BY sur chacune de mes 2 recherches fulltext, au lieu d'un ORDER BY sur l'ensemble des 2 requêtes fulltext.
J'obtiens quasiment ce que je veux mais j'aurais préféré avoir un seul ORDER BY par groupe de recherches fulltext.
Marsh Posté le 05-08-2008 à 16:29:33
Hello,
comment faire pour qu'une telle requête fonctionne ?
(SELECT f.AC FROM familyA f WHERE f.AC='TF105322')
UNION DISTINCT
(SELECT f.AC FROM familyA f WHERE f.AC='tf105351')
UNION DISTINCT
((SELECT f.AC FROM familyA f WHERE MATCH (f.NAME, f.SYNONYM, f.DESC) AGAINST ('+muscle*' IN BOOLEAN MODE))
UNION DISTINCT
(SELECT f.AC FROM familyA f, genes g WHERE MATCH (g.DESC, g.SYMBOL, g.TID, g.GID) AGAINST ('+muscle*' IN BOOLEAN MODE)) ORDER BY f.AC)
UNION DISTINCT
(SELECT f.AC FROM familyA f WHERE f.AC='Tf105323')
C'est un dire un sous-UNION dans un UNION ?
Est-ce possible ?
Merci