Oracle自定义排序

时间:2010-06-15 19:56:44

标签: sql oracle

查询...

select distinct name from myTable 

返回一系列以下列字符序列开头的值...

ADL*
FG*
FH*
LAS*
TWUP*

其中'*'是字符串的其余部分。

我希望通过以下方式进行排序......

ADL*
LAS*
TWUP*
FG*
FH*

但是我还希望通过时尚在标准顺序中对每个名称进行排序。所以,举个例子,如果我有以下值

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

我希望它像这样排序......

ADL77777
ADL88888
ADL99999
LAS2
TWUP-1
FG999
FH3

我最初认为我可以完成这个过滤通过解码(blah)执行一个命令,在解码中有一些类似的技巧,但我一直无法完成它。任何见解?

2 个答案:

答案 0 :(得分:9)

高飞和冗长,但应该有效:

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;

不确定6是否是对其他项目进行排序的正确位置,但很明显如何解决这个问题。至少很清楚发生了什么,即使我不知道你为什么这样做。

编辑:如果这些是唯一的值,您可以更改第4行和第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;

另一个编辑:再次,如果这些是唯一的值,您可以进一步简化。由于唯一一个故障是F *系列,你可以强制它们到最后,并使用实际的第一个字母表示所有其他的。这更简单,但过分依赖于我偏好的确切值。另一方面,它确实删除了许多看似不必要的substr调用:

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

答案 1 :(得分:3)

问题是您的前缀包含可变数量的字符。这是部署正则表达式的好时机(如果你有10g或更高)。

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>

如果早期版本的Oracle我们可以使用OWA_PATTERN.AMATCH()函数达到同样的效果:

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>