Mauvaise utilisation de L'UNION et de L'ordre par?

comment utiliser union et order by 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 de l'erreur

#1221 - Incorrect usage of UNION and ORDER BY

n'importe qui peut aider ?

49
demandé sur Fabiotk 2011-07-18 16:10:00

5 réponses

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

66
répondu Tudor Constantin 2014-11-28 23:50:08

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

a dit que, il n'est pas obligatoire pour MySQL de garder le tri intérieur dans la clause extérieure-bien qu'il sera probablement le faire car il a besoin de trier des lignes de toute façon pour calculer les clauses correspondantes LIMIT .

27
répondu Álvaro González 2015-07-13 16:18:15

explication:

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

substatement union all substatement union all substatement [ order by - clause] [ limit - clause]

où" substatement " peut éventuellement être entouré de ( et ) . Quelques exemples pratiques:

  • 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 " substatement "avec des bretelles, vous doit entourer tous les autres " substatement "s avec des 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 .)

à Défaut de 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 " substatement " peut contenir where , group by , having , join , limit , mais pas order by .

si vous souhaitez utiliser order by , le " " substatement " qui contient order by doit être entouré de bretelles. (Ce qui signifie qu'ils ne sont plus optionnels.)

maintenant, si nous regardons à nouveau la syntaxe:

"substatement union all substatement union all substatement [ order by -la clause] [ limit -clause]

nous pouvons voir que la totalité de l'énoncé union se termine par une option order by / limit . Ces deux mots-clés s'appliquent à la totalité de la déclaration union , pas seulement le dernier" "substatement ":

  • 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-clé limit peut également être appliqué à l'individu " substatement "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 au dernier" substatement "(par opposition à la totalité de l'énoncé union ), vous doit entourent le dernier " substatement " avec des accolades:

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

appliquer limit à la dernière " sous-déclaration et aussi à la totalité 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 que l'application de order by à sous-déclaration "s est sans signification parce que les docs ont explicitement déclaré que order by est seulement garanti ( cf. ) à travailler lorsqu'elle est appliquée à l'ensemble de l'énoncé union :

& puncsp; "1519920920 – - § -   ..l'utilisation de ORDER BY individuels SELECT états implique rien quant à l'ordre dans lequel les lignes apparaissent dans le résultat final..

la seule façon order by aurait un sens dans un " "substatement "est si vous le combinez avec limit :

–§– ..l'utilisation de L'ORDRE PAR dans ce contexte est typiquement en conjonction avec LIMIT , de sorte qu'il est utilisé pour déterminer le sous-ensemble des lignes sélectionnées pour récupérer pour le SELECT , même si elle ne affecte nécessairement l'ordre de ces lignes dans le résultat final UNION .

aussi, si vous voulez combiner select into avec union , il y aura plus de" gotchas " à surveiller. Voir numéro 32858 à ce sujet.

22
répondu Pacerier 2017-05-23 12:34:41

La correcte 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
0
répondu Diego Vintimilla Espinoza 2016-05-24 05:10:59

try () 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);
0
répondu anil kumar meena 2018-09-04 06:19:22