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 ?
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
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 .
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 allsubstatementunion allsubstatement [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 allsubstatementunion allsubstatement [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 BYindividuelsSELECTé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 leSELECT, même si elle ne affecte nécessairement l'ordre de ces lignes dans le résultat finalUNION.
aussi, si vous voulez combiner select into avec union , il y aura plus de" gotchas " à surveiller. Voir numéro 32858 à ce sujet.
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
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);