2010-06-15 6 views
3

La requête ...Oracle tri personnalisé

select distinct name from myTable 

retourne un tas de valeurs qui commencent par les séquences de caractères suivantes ...

ADL* 
FG* 
FH* 
LAS* 
TWUP* 

Où « * » est le reste de la chaîne .

Je veux faire une commande par triant de la manière suivante ...

ADL* 
LAS* 
TWUP* 
FG* 
FH* 

Mais je veux aussi trier au sein de chaque nom dans l'ordre standard de la mode. Ainsi, un exemple, si je les valeurs suivantes

LAS-21A 
TWUP-1 
FG999 
FH3 
ADL99999 
ADL88888 
ADL77777 
LAS2 

Je veux qu'il soit trié comme ça ...

ADL77777 
ADL88888 
ADL99999 
LAS2 
TWUP-1 
FG999 
FH3 

Je pensais d'abord que je pouvais y arriver vias faire une commande par decode (blah) avec un peu de tricherie à l'intérieur du décodage mais j'ai été incapable de l'accomplir. Des idées?

Répondre

9

Dingo et bavard, mais devrait fonctionner:

select name, case when substr (name, 1, 3) = 'ADL' then 1 
        when substr (name, 1, 3) = 'LAS' then 2 
        when substr (name, 1, 4) = 'TWUP' then 3 
        when substr (name, 1, 2) = 'FG' then 4 
        when substr (name, 1, 2) = 'FH' then 5 
        else 6 
      end SortOrder 
from myTable 
order by 2, 1; 

Je ne sais pas si 6 est le bon endroit pour trier les autres éléments, mais il est évident comment résoudre ce problème. Au moins, il est clair ce qui se passe, même si je ne sais pas pourquoi vous le faites de cette façon.

EDIT: Si ce sont les seules valeurs, vous pouvez changer les lignes 4 et 5:

select name, case when substr (name, 1, 3) = 'ADL' then 1 
        when substr (name, 1, 3) = 'LAS' then 2 
        when substr (name, 1, 4) = 'TWUP' then 3 
        when substr (name, 1, 1) = 'F' then 4 
        else 6 
      end SortOrder 
from myTable 
order by 2, 1; 

AUTRE EDIT: Et encore, si ceux-ci sont les seules valeurs, vous pouvez simplifier encore plus . Puisque le seul en panne est la série F *, vous pouvez les forcer à la fin, et utiliser la première lettre réelle pour tous les autres. C'est plus simple, mais repose trop sur les valeurs exactes de ma préférence. D'autre part, il ne supprime la plupart des appels apparemment inutiles à substr:

select name, case when substr (name, 1, 1) = 'F' then 'Z' 
        else name 
      end SortOrder 
from myTable 
order by 2, 1; 
+0

Eh oui, bien que vous pouvez utiliser alternativement là au lieu Likès de SUBSTR(). Je ne suis pas sûr de ce qui serait le plus rapide. –

+0

Bonne prise sur cette édition finale. Merci monsieur! – Carter

3

Le problème est que le préfixe contient un nombre variable de caractères. C'est un bon moment pour déployer des expressions régulières (si vous avez 10g ou plus).

SQL> select cola 
    2 from t34 
    3 order by decode(regexp_substr(cola, '[[:alpha:]]+') 
    4     , 'ADL' , 10 
    5     , 'LAS', 20 
    6     , 'TWUP', 30 
    7     , 'FG' , 40 
    8     , 'FH' , 50 
    9     , 60) 
10   , cola 
11/

COLA 
---------- 
ADL77777 
ADL88888 
ADL99999 
LAS-21A 
LAS2 
TWUP-1 
FG999 
FH3 

8 rows selected. 

SQL> 

Si les versions précédentes d'Oracle, nous pouvons utiliser la fonction OWA_PATTERN.AMATCH() dans le même sens:

SQL> select cola 
    2 from t34 
    3 order by decode(owa_pattern.amatch(cola, 1, '^[A-Z]+') 
    4     , 'ADL' , 10 
    5     , 'LAS', 20 
    6     , 'TWUP', 30 
    7     , 'FG' , 40 
    8     , 'FH' , 50 
    9     , 60) 
10   , cola 
11/

COLA 
---------- 
ADL77777 
ADL88888 
ADL99999 
FG999 
FH3 
LAS-21A 
LAS2 
TWUP-1 

8 rows selected. 

SQL> 
+0

Merci, cela aurait certainement fait l'affaire. Malheureusement, je suis seulement sur 9. – Carter

Questions connexes