74 votes

Utilisation incorrecte de UNION et ORDER BY ?

Comment puis-je utiliser syndicat y commande par 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

Donnez-moi une erreur

#1221 - Incorrect usage of UNION and ORDER BY

Quelqu'un peut-il m'aider ?

97voto

Tudor Constantin Points 11393

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 le ORDER BY à la fin de la deuxième requête

36voto

Álvaro G. Vicario Points 57607

Entre parenthèses :

(
    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
)

Cela dit, il n'est pas obligatoire pour MySQL de conserver le tri interne dans la clause externe, bien qu'il soit plus facile de le faire. probablement le faire puisqu'il doit de toute façon trier les rangées pour calculer le montant correspondant LIMIT clauses.

1 votes

Oui, il me manquait aussi la parenthèse, et l'avoir ajoutée l'a réparée.

30voto

Pacerier Points 15960

Explication :

Il est important de comprendre comment cela fonctionne pour éviter les "gotchas" dans des cas d'utilisation similaires. Notez que union La syntaxe de l'article est quelque peu "spéciale" :

<em>sous-statut </em>union all <em>sous-statut </em>union all <em>sous-statut </em> [ order by -clause] [ limit -clause]

où " sous-statut "peut éventuellement être entouré de ( y ) . Quelques exemples concrets :

  • 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-statut " avec un appareil dentaire, vous doit entourent tous les autres " sous-statut "s" avec des accolades :

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

(A noter que le point ci-dessus n'est pas mentionné dans le document 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-statut "peut contenir where , group by , having , join , limit mais pas order by .

Si vous souhaitez utiliser order by le " sous-statut "qui contient order by doit être entouré d'accolades. (Ce qui signifie qu'elles ne sont plus facultatives).

Maintenant, si nous regardons à nouveau la syntaxe :

<em>sous-statut </em>union all <em>sous-statut </em>union all <em>sous-statut </em> [ order by -clause] [ limit -clause]

nous pouvons voir que l'ensemble de la union se termine par une option order by / limit . Ces deux mots-clés s'appliquent à l'ensemble du union et pas seulement le dernier " sous-statut " :

  • 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 limit Le mot-clé peut également être appliqué à des " sous-statut "s :

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

    mysql>

Si vous voulez appliquer limit jusqu'au dernier " sous-statut "(par opposition à l'ensemble du union déclaration), vous doit entourent le dernier " sous-statut " avec des accolades :

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

    mysql>

Pour postuler limit jusqu'au dernier " sous-statut " et aussi à l'ensemble du union déclaration, utiliser :

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

    mysql>

C'est la même chose avec 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 qu'en appliquant order by à " sous-statut "s est inutile parce que les docs ont explicitement a déclaré que order by est seulement garanti ( cf. ) pour fonctionner lorsqu'il est appliqué à l'ensemble de la union déclaration :

-§-   ..l'utilisation de ORDER BY pour les particuliers SELECT Les déclarations n'impliquent rien quant à l'ordre dans lequel les lignes apparaissent dans le résultat final .

Le seul moyen order by aurait un sens dans un " sous-statut "est si vous le combinez avec limit :

-§-   l'utilisation de ORDER BY dans ce contexte est typiquement en conjonction avec LIMIT afin qu'il soit utilisé pour déterminer le sous-ensemble des lignes sélectionnées à récupérer pour l'opération de recherche. SELECT même si elle n'est pas nécessairement l'ordre de ces lignes dans la version finale. UNION résultat.

Aussi, si vous voulez combiner select **_into_** con union il y aura plus de "gotchas" à surveiller. Voir numéro 32858 à ce sujet.

2voto

Rithvik Mundra Points 1

L'utilisation des parenthèses a résolu mon problème lors de l'utilisation des clauses Order by et limit dans la requête. Mon exigence était d'obtenir la ligne supérieure et inférieure du tableau avec une certaine condition et le code suivant a fonctionné pour moi :

(SELECT column1, column2
FROM table1
ORDER BY column1, column2
LIMIT 1)

UNION

(SELECT column1, column2
FROM table2
ORDER BY column1, column2 
LIMIT 1)

0voto

La bonne réponse 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X