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 all
substatementunion 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
substatementunion 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
individuelsSELECT
é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);