Сортировка списка значений, который содержит буквы, а также цифры в определенном порядке - PullRequest
0 голосов
/ 04 февраля 2019

У меня проблема в SQL Oracle, я пытаюсь создать представление, содержащее значения с буквами и цифрами, и хочу отсортировать их в определенном порядке.

Вот мой запрос:

create or replace view table1_val (val, msg_text) as 
select 
    val, msg_text
from 
    table_val
where 
    val in ('L1','L2','L3','L4','L5','L6','L7','L8','L9','L10','L11','L12','L13','L14','G1','G2','G3','G4') 
order by lpad(val, 3);

Значения отображаются следующим образом:

G1,G2,G3,G4,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10,L11,L12,L13

Дело в том, что я хочу сначала отобразить значения L, а затем значения G, как в условии where.Столбец val равен VARCHAR2(3 CHAR).Столбец msg_text не имеет значения.Может ли кто-нибудь помочь мне с этим?Я использую Oracle 12C.

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

Вы должны интерпретировать вторую часть столбца val как число

order by 
  case when val like 'L%' then 0 else 1 end,
  to_number(substr(val,2))

. Это хорошо работает для ваших текущих данных, но может не сработать в будущем, если новая запись будет добавлена ​​с нечисловым значением.структура.

Более консервативным (и более трудным для написания), но безопасным было бы использовать декодирование для всех текущих ключей, упорядочивая неизвестные ключи в последней позиции (id = 18 в примере):

order by 
decode(
'L1',1,
'L2',2,
'L3',3,
'L4',4,
'L5',5,
'L6',6,
'L7',7,
'L8',8,
'L9',9,
'L10',10,
'L11',11,
'L12',12,
'L13',13,
'G1',14,
'G2',15,
'G3',16,
'G4',17,18)
0 голосов
/ 04 февраля 2019

Другим вариантом, который следует учитывать, может быть использование регулярных выражений, таких как

SQL> with table1_val (val) as
  2    (select 'L1'   from dual union all
  3     select 'L26'  from dual union all
  4     select 'L3'   from dual union all
  5     select 'L21'  from dual union all
  6     select 'L11'  from dual union all
  7     select 'L4'   from dual union all
  8     select 'G88'  from dual union all
  9     select 'G10'  from dual union all
 10     select 'G2'   from dual
 11    )
 12  select val
 13  from table1_val
 14  order by regexp_substr(val, '^[[:alpha:]]+') desc,
 15           to_number(regexp_substr(val, '\d+$'));

VAL
---
L1
L3
L4
L11
L21
L26
G2
G10
G88

9 rows selected.

SQL>
0 голосов
/ 04 февраля 2019

Вы не можете ничего сделать в зависимости от порядка WHERE условия

Но вы можете использовать CASE для ORDER BY

ORDER BY CASE 
            WHEN SUBSTR(val, 1, 1) = 'L' THEN 1
            WHEN SUBSTR(val, 1, 1) = 'G' THEN 2
            ELSE 3
         END,
         TO_NUMBER (SUBSTR(val, 2, 10));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...