Utilisation incorrecte de UNION et ORDER BY?

Comment puis-je utiliser l’ union et l’ ordre dans mysql?

select * from _member_facebook inner join _member_pts ON _member_facebook._fb_owner=_member_pts._username where _member_facebook._promote_point = 9 ORDER BY RAND() limit 2 UNION ALL select * from _member_facebook inner join _member_pts ON _member_facebook._fb_owner=_member_pts._username where _member_facebook._promote_point = 8 limit 3 

me donner une erreur

 #1221 - Incorrect usage of UNION and ORDER BY 

n’importe qui peut aider?

Essayez avec:

 ( select * from _member_facebook inner join _member_pts ON _member_facebook._fb_owner=_member_pts._username where _member_facebook._promote_point = 9 ORDER BY RAND() limit 2 ) UNION ALL ( select * from _member_facebook inner join _member_pts ON _member_facebook._fb_owner=_member_pts._username where _member_facebook._promote_point = 8 limit 3 ) 

Bien que, je pense que vous devriez mettre la clause ORDER BY à la fin de la deuxième requête

Avec parenthèse:

 ( SELECT * FROM _member_facebook INNER JOIN _member_pts ON _member_facebook._fb_owner =_member_pts._username WHERE _MEMBER_FACEBOOK._PROMOTE_POINT = 9 ORDER BY RAND() LIMIT 2 ) UNION ALL ( SELECT * FROM _MEMBER_FACEBOOK INNER JOIN _MEMBER_PTS ON _MEMBER_FACEBOOK._FB_OWNER =_MEMBER_PTS._USERNAME WHERE _MEMBER_FACEBOOK._PROMOTE_POINT = 8 LIMIT 3 ) 

Autrement dit, il n’est pas obligatoire pour MySQL de conserver le sorting interne dans la clause external – bien que cela le fasse probablement car il doit de toute façon sortinger les lignes pour calculer les clauses LIMIT correspondantes.

Explication:

Il est important de comprendre comment cela fonctionne pour éviter les “pièges” dans des cas d’utilisation similaires. Notez que la syntaxe de l’ union est quelque peu “spéciale”:

Subatement union all sous-états union all sous-états [ order by -clause] [clause- limit ]

où ” substatement ” peut éventuellement être entouré par ( et ) . Quelques exemples de travail:

  •  select 1 union all (select 2); select 1 union all select 2 union all (select 3); select 1 union all (select 2) union all select 3; select 1 union all (select 2) union all (select 3); select 1 union all (select 2) union all (select 3) union all select 4; select 1 union all (select 2) union all select 3 union all (select 4); 

Cependant , si vous entourez le premier ” sous-élément ” d’accolades, vous devez entourer tous les autres ” sous-éléments ” d’accolades:

  •  (select 1) union all (select 2) union all (select 3); 

(Notez que le point ci-dessus n’est pas mentionné dans les documents officiels .)

Ne pas le faire est une erreur de syntaxe:

  •  mysql> (select 1) union all select 2; -- error because not all "substatement"s are braced ERROR 1064 (42000): You have an error in your SQL syntax; check the... mysql> (select 1) union all (select 2) union all select 3; -- error because not all "substatement"s are braced ERROR 1064 (42000): You have an error... mysql> (select 1) union all select 2 union all (select 3); -- error because not all "substatement"s are braced ERROR 1064 (42000): You have an error... 

Ensuite, chaque ” sous-composant ” peut contenir where , group by , having , join , limit , mais pas order by .

Si vous souhaitez utiliser l’ order by , le ” sous-composant ” qui contient l’ order by doit être entouré d’accolades. (Ce qui signifie qu’ils ne sont plus optionnels.)

Maintenant, si nous regardons à nouveau la syntaxe:

Subatement union all sous-états union all sous-états [ order by -clause] [clause- limit ]

nous pouvons voir que la déclaration d’ union complète se termine par un order by optionnel order by / limit . Ces deux mots-clés s’appliquent à l’ensemble union déclaration d’ union , et pas seulement au dernier ” sous-composant “:

  •  mysql> select 1 -> union all -> select 2 limit 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec) mysql> 

Nous avons mentionné précédemment que le mot limit clé limit peut également être appliqué à des ” sous-éléments ” individuels:

  •  mysql> select 1 limit 1 -> union all -> select 2; +---+ | 1 | +---+ | 1 | | 2 | +---+ 2 rows in set (0.00 sec) mysql> 

Si vous souhaitez appliquer une limit au dernier ” sous-élément ” (par opposition à la totalité union instruction union ), vous devez entourer le dernier ” sous-composant ” d’accolades:

  •  mysql> select 1 -> union all -> (select 2 limit 1); +---+ | 1 | +---+ | 1 | | 2 | +---+ 2 rows in set (0.00 sec) mysql> 

Pour appliquer la limit au dernier ” sous-composantet aussi à la totalité union déclaration d’ union , utilisez:

  •  mysql> select 1 -> union all -> (select 2 limit 1)limit 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set (0.00 sec) mysql> 

C’est pareil avec l’ order by :

  •  mysql> select 1 -> union all -> (select 2 order by 1)order by 1; +---+ | 1 | +---+ | 1 | | 2 | +---+ 2 rows in set (0.00 sec) mysql> 

Mais notez que l’application de la order by à « substatement » n’a pas de sens car les docs ont explicitement déclaré que la order by est uniquement garantie ( cf. ) pour fonctionner sur l’ensemble union déclaration d’ union :

–§– ..l’utilisation d’ ORDER BY pour des SELECT individuelles n’implique rien dans l’ordre dans lequel les lignes apparaissent dans le résultat final.

La seule façon dont l’ order by aurait un sens dans un ” sous-composant ” est si vous le combinez avec la limit :

–§– ..L’utilisation d’ORDER BY dans ce contexte est généralement associée à LIMIT , de sorte qu’il est utilisé pour déterminer le sous-ensemble des lignes sélectionnées à récupérer pour le SELECT , même si cela n’affecte pas nécessairement l’ordre de celles-ci. lignes dans le résultat UNION final.

De plus, si vous voulez combiner la select into avec l’ union , il y aura plus de «pièges» à surveiller. Voir le numéro 32858 à ce sujet.

Le correct est:

 (SELECT * FROM _member_facebook INNER JOIN _member_pts ON _member_facebook._fb_owner=_member_pts._username WHERE _member_facebook._promote_point = 9 LIMIT 2) UNION ALL (SELECT * FROM _member_facebook INNER JOIN _member_pts ON _member_facebook._fb_owner=_member_pts._username WHERE _member_facebook._promote_point = 8 LIMIT 3) ORDER BY 1 

essayez () je pense comme

 (SELECT CITY,LENGTH(CITY) FROM STATION WHERE LENGTH(CITY)=(SELECT MIN(LENGTH(CITY)) FROM STATION) ORDER BY CITY LIMIT 1) UNION ALL (SELECT CITY,LENGTH(CITY) FROM STATION WHERE LENGTH(CITY)=(SELECT MAX(LENGTH(CITY)) FROM STATION) ORDER BY CITY LIMIT 1);