comment puis-je 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
donne moi une erreur
#1221 - Incorrect usage of UNION and ORDER BY
quelqu'un 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 des 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 que probablement le fasse car il doit quand même trier les lignes pour calculer les clauses LIMIT
correspondantes.
Il est important de comprendre comment cela fonctionne pour éviter les "pièges" dans des cas d'utilisation similaires. Notez que la syntaxe de union
est quelque peu "spéciale":
substatement
union all
substatementunion all
substatement [Clauseorder by
] [Clauselimit
]
où "substatement" peut éventuellement être entouré de (
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 "substatement" avec des accolades, vous devez entourez tous les autres "substatement} _" avec des accolades:
(select 1) union all (select 2) union all (select 3);
(Notez que le point ci-dessus n’est pas mentionné dans la documentation officielle .)
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 "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é d'accolades. (Ce qui signifie qu'ils ne sont plus facultatifs.)
Maintenant, si nous examinions à nouveau la syntaxe:
substatement
union all
substatementunion all
substatement [Clauseorder by
] [Clauselimit
]
nous pouvons voir que l'instruction union
entière se termine par un order by
limit
facultatif. Ces deux mots clés s'appliquent à la totalité de l'instruction union
, et pas seulement au dernier "substitution":
mysql> select 1
-> union all
-> select 2 limit 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
mysql>
Nous avons déjà mentionné que le mot clé limit
peut également être appliqué à des "substatement}" 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 limit
au dernier "substatement}" (par opposition à la totalité de l'instruction union
), vous _/devez entourez 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>
Pour appliquer limit
au dernier "substatement" et à la totalité de l'instruction 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 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
à "substatement" s est sans signification car les documents ont explicitement déclaré que order by
n'est garanti ( cf. ) que lorsque appliqué à l'ensemble de l'instruction union
:
–§– .. L'utilisation de
ORDER BY
pour des instructionsSELECT
individuelles n'implique en aucun cas l'ordre dans lequel les lignes apparaissent dans le résultat final.
La seule façon dont order by
aurait du sens dans un "substatement} _" est si vous le combinez avec limit
:
–§– ... l'utilisation de ORDER BY dans ce contexte est généralement associée à
LIMIT
, de sorte qu'elle est utilisée pour déterminer le sous-ensemble des lignes sélectionnées à extraire pourSELECT
, même si affecte nécessairement l'ordre de ces lignes dans le résultat finalUNION
.
De plus, si vous voulez combiner select into
avec union
, vous aurez plus de "pièges" à surveiller. Voir numéro 32858 à ce sujet.
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);
Je pense que l’utilisation de parenthèses est obligatoire si vous utilisez ordre ou limite ou les deux. J'ai essayé de travailler sur une requête en utilisant limit et order de manière interchangeable sans parenthèse et la requête ne fonctionnait pas. Cela n'a fonctionné qu'après avoir ajouté une parenthèse.
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