Home > other >  Oracle - Sort by letters first then numbers
Oracle - Sort by letters first then numbers

Time:07-14

I want to sort the following data items in the order they are presented below ( letters then numbers ) :

AA

AB

AC

..

00

01

02

..

99

However, my query - using Order by xxxxx ASC - based on ASCII code - which retrieves all numbers first and then letters as shown :

00

01

..

99

AA

AB

..

ZZ

Any tricks to make it sort more appropriately?

THANKS!

CodePudding user response:

One way to do this would be to prioritize the ordering of items by alphabets using case when condition and after that to use the regular ordering. This way the priority sort would be on alphabets then numbers, followed by ordering within the respective categories

Eg:

select a.*
  from t a
order by case when translate(x,'0123456789','         ')<>x then 1 else 0 end
         ,x  

 -------- 
| output |
 -------- 
| AA     |
| AB     |
| AC     |
| AZ     |
| 00     |
| 01     |
| 02     |
| 4      |
 -------- 

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=dff7e6805f1b59501d59cb91194cf1a0

CodePudding user response:

Another option is to use regular expressions so that digits are sorted first, then the rest (and that "rest" will be letters):

SQL> with test (col) as
  2    (select '00' from dual union all
  3     select 'AB' from dual union all
  4     select 'AC' from dual union all
  5     select '01' from dual union all
  6     select '99' from dual union all
  7     select 'ZZ' from dual
  8    )
  9  select col
 10  from test
 11  order by regexp_substr(col, '\d'), col
 12  /

CO
--
00
01
99
AB
AC
ZZ

6 rows selected.

SQL>

That's OK for relatively small data sets, but - regular expressions seem to be somewhat slow when we have to work with large data sets so - see if it helps.

CodePudding user response:

You can also use a regular expression to achieve the same where '\D' will match any non-digit.

    with t(x) as(select 'AZ' from dual union all
      select 'AA' from dual union all
      select 'AB' from dual union all
      select 'AC' from dual union all
      select '00' from dual union all
      select '01' from dual union all
      select '02' from dual union all
      select '4' from dual)

    select x
       from t
      order by (regexp_substr(x, '\D')), x 
  • Related