Вопрос по oracle, sorting, plsql, sql – oracle PL / SQL: сортировка строк

1

Я запускаю запрос с заказом, но мой столбец не соответствует порядку, в котором я хочу быть

Я хотел это так:

PRODUCT

PROD_1
PROD_2
PROD_3
PROD_4
PROD_5
PROD_6
PROD_7
PROD_8
PROD_9
PROD_10

но это дает мне это

PRODUCT

PROD_1
PROD_10
PROD_2
PROD_3
PROD_4
PROD_5
PROD_6
PROD_7
PROD_8
PROD_9

Ваш Ответ

4   ответа
0
    SELECT to_number(substr(colname,INSTR(column_name,'_')+1))) prodno, column_name 
    from table_name
    order by prodno

Не очень элегантное решение, но это должно сработать. (Поскольку у меня нет доступа к Oracle, параметры для работы могут нуждаться в корректировке.) Это сначала определяет положение_ используя который он получает число, используя подстроку, которая затем преобразуется в число. Возможно, вам также придется посмотреть на производительность, если размер таблицы большой

1

Вам либо нужно будет добавить 0 для каждой позиции, например 01 для чисел 1-99 или 001 для 1-999. ИЛИ вам придется разделить числовые значения и отсортировать по двум различным столбцам.

Спроси Тома

+1: @JamilSmith - Хотя всегда соблазнительно удовлетворить несколько потребностей одним столбцом, он также создает дополнительные ограничения. Имея обаname поле иsort order поле, вы можете иметь любое имя с любым заказом, который вам нравится. В противном случае имя влияет на порядок так, как вы этого не желаете. Такие как это.(But, otherwise, PRODUCT_001 really is the way to get this using just the name field.)
0

Вы пытаетесь лексографически отсортировать что-то, что на самом деле является частично числовым. Вы могли бы добавлять префиксы к нулю (то есть PROD_000001), но это хрупко. В реальном приложении я предполагаю, что Prod 10 фактически позже во времени, чем Prod 1, поэтому вы упорядочиваетесь по дате создания и времени.

0

Вам нужно будет выполнить сортировку дважды (обратите внимание, что я изменил с regexp_replace на regexp_substr, чтобы учесть нулевое возвращаемое значение)

with
    a as (
    select 'PROD_1' product from dual union all 
    select 'PROD_10' product from dual union all 
    select 'PROD_2' product from dual union all 
    select 'PROD_3' product from dual union all 
    select 'PROD_4' product from dual union all 
    select 'PROD_5' product from dual union all 
    select 'PROD_6' product from dual union all 
    select 'PROD_7' product from dual union all 
    select 'PROD_8' product from dual union all 
    select 'PROD_9' product from dual union all 
    select 'DECEAD_1' product from dual union all 
    select 'DECEAD_10' product from dual union all 
    select 'DECEAD_2' product from dual union all 
    select 'DECEAD_20' product from dual union all 
    select 'TREE_FROG' product from dual 
    )
    select PRODUCT
          , regexp_substr(product,'[^[:digit:]]*')  --return all non numeric
          , regexp_substr(product,'[0-9]+') 
          from a 
    order by regexp_substr(product,'[^[:digit:]]*')  ,
             TO_NUMBER(regexp_substr(product,'[0-9]+')) --note explicit numeric cast
    ;

Похожие вопросы