2010-07-04 4 views
8

Je voudrais obtenir à partir d'une seule table, toutes les lignes, mais les commander de différentes manières. Par exemple, j'écrireSELECT UNION et ORDER BY dans mysql .. comment?

(SELECT * FROM table1 
ORDER BY fieldA ASC LIMIT 3 
) 
UNION 
(
SELECT * FROM table1 
ORDER BY FieldB DESC 
) 

Il fonctionne, excpet que le second ordre par (FIELDB DESC) est ignoré ... Quelqu'un sait pourquoi? Merci

+2

Voir [UNION Syntaxe] (http://dev.mysql.com/doc/refman/5.0/en/union.html) . Rechercher 'l'utilisation de ORDER BY pour des instructions SELECT individuelles ne signifie rien sur la commande'. Voir également [ce post SO] (http://stackoverflow.com/questions/3163503/sorting-union-queries-in-mysql/3163526#3163526). – Mike

+0

wow, ça a marché ... mais comment ça marche? mmm .. je suis un peu confus ..! – stighy

Répondre

17

L'opérateur UNION effectue un tri implicite dans le cadre de l'opération d'union (IIRC, sur la (les) colonne (s) de clé).

Si vous voulez un autre tri dans le résultat, vous devez appliquer un ORDER BY à la sélection avec union.

Dans votre cas, vous avez besoin d'un moyen de faire la distinction entre la première sélection et la seconde, afin que vous puissiez commander l'union correctement. Quelque chose comme (non testé):

(SELECT table1.*, 0 AS TMP_ORDER FROM table1 ORDER BY fieldA ASC LIMIT 3) 
UNION 
(SELECT table1.*, 1 AS TMP_ORDER FROM table1) 
ORDER BY TMP_ORDER ASC, 
CASE WHEN TMP_ORDER = 0 THEN fieldA ELSE 0 END ASC, 
CASE WHEN TMP_ORDER = 1 THEN fieldB ELSE 0 END DESC 

Le problème avec cette approche est que vous aurez des doublons pour les trois lignes sélectionnées dans le cadre de la première requête dans la UNION (car les colonnes ne correspondent pas tout à fait).

Êtes-vous sûr de ne pas pouvoir utiliser deux déclarations SELECT à la place?

+0

@Mike, cette question ne nécessite pas de tri distinct basé sur unionorder. C'est là qu'intervient l'instruction 'CASE'. –

+0

Le 'select *' externe n'est pas nécessaire, de même que la requête interne' order by' ne fait rien dans la 2ème requête car il n'y a pas de limite: '(sélectionnez t1. *, 0 tmp_order à partir de t1 order par fieldA asc limite 3) union (sélectionner t2. *, 1 à partir de t2) ordonner par tmp_order, case ... ' – Donnie

+0

+1 @Mike - cette réponse trie uniquement par quelle sous-requête les données proviennent , aucun tri de second niveau pour s'assurer que FieldA et FieldB sont également triés à partir de leurs requêtes respectives. La réponse ici inclut le tri de second niveau. – mdma

1

Vous pouvez déclarer la deuxième SELECT en conséquence fixe ..

SELECT 'First select option' AS something 

UNION 

SELECT something 
FROM(
    (SELECT something 
    FROM SomeTable 
    ORDER BY something ASC)) FixedResult