Я спросил, что это за тип данных, потому что сортировка выглядела как сортировка строк , а не чисел .
Посмотрите на это. Во-первых, только одно выражение в порядке по выражению:
SQL> with test (seq_diff) as
2 (select -990 from dual union all
3 select -610 from dual union all
4 select -1350 from dual union all
5 select -1340 from dual
6 )
7 select *
8 from test
9 order by decode(seq_diff, abs(seq_diff), seq_diff, null);
SEQ_DIFF
----------
-990
-1340
-1350
-610
SQL>
Как они сортируются? Это не так. В соответствии с образцом набора данных, seq_diff
не равно abs(seq_diff)
, поэтому порядок перемещается в null
, что приводит к «случайным» упорядоченным значениям. Они вообще не сортируются.
Теперь давайте добавим еще один decode
в порядок:
SQL> with test (seq_diff) as
2 (select -990 from dual union all
3 select -610 from dual union all
4 select -1350 from dual union all
5 select -1340 from dual
6 )
7 select *
8 from test
9 order by decode(seq_diff, abs(seq_diff), seq_diff, null),
10 decode(seq_diff, abs(seq_diff), null, seq_diff) desc;
SEQ_DIFF
----------
-990
-610
-1350
-1340
SQL>
Первый decode
ничего не сделал, так какесли его не существует, мы переходим ко второму decode
. Опять же, согласно набору данных, нет seq_diff
равно abs(seq_diff)
, но на этот раз он возвращает seq_diff
. Документация (как @krokodilko упомянул в своем комментарии) гласит:
- Функция DECODE возвращает значение того же типа данных, что и первый результат в списке.
- Еслипервый результат равен NULL, затем возвращаемое значение преобразуется в VARCHAR2.
- это наш случай, поэтому возвращаемое значение (
seq_diff
) преобразуется в varchar2
- Если первый результат имеет тип данных CHAR, возвращаемое значение преобразуется в VARCHAR2.
- Если совпадений не найдено, возвращается значение по умолчанию.
- Если по умолчаниюпропущен и совпадений не найдено, возвращается NULL.
Еще раз: наш случай второй:
decode(seq_diff, abs(seq_diff), null, seq_diff)
----
the first result is NULL
Поэтому seq_diff
преобразуется вСтрока и значения сортируются как таковые. Давайте проверим, что:
SQL> with test (seq_diff) as
2 (select -990 from dual union all
3 select -610 from dual union all
4 select -1350 from dual union all
5 select -1340 from dual
6 )
7 select *
8 from test
9 order by to_char(seq_diff) desc;
SEQ_DIFF
----------
-990
-610
-1350
-1340
SQL>
Видите? Тот же самый результат, который мы получили с order by decode(seq_diff, abs(seq_diff), null, seq_diff) desc;
Последняя часть вашего предложения order by
тривиальна (abs(dist_diff)
), я думаю, объяснять это не нужно.
Вот почему вы получили странный результат с DECODE
;на самом деле, это ожидаемое поведение.