Сортировка буквенно-цифрового идентификационного номера

У меня есть база данных, в которой каждая транзакция получает буквенно-цифровой идентификатор. Когда я пишу свой запрос и использую Order by it, я получаю неправильную последовательность.

Например:

TRN_ID      TRNDTE
000002DAAW  2020-09-12 03:45:24
000002DAAX  2020-09-12 03:45:32
000002DAAY  2020-09-12 03:45:34
000002DAAZ  2020-09-12 03:45:38
000002DAA0  2020-09-12 03:35:16
000002DAA1  2020-09-12 03:35:25
000002DAA2  2020-09-12 03:35:26
000002DAA3  2020-09-12 03:35:30
000002DAA4  2020-09-12 03:35:39
000002DAA5  2020-09-12 03:35:40
000002DAA6  2020-09-12 03:35:44
000002DAA7  2020-09-12 03:36:00
000002DAA8  2020-09-12 03:36:01
000002DAA9  2020-09-12 03:36:05
000002DABA  2020-09-12 03:48:12 <-
000002DABB  2020-09-12 03:48:15
000002DABC  2020-09-12 03:48:32
000002DABD  2020-09-12 03:48:33
000002DABE  2020-09-12 03:48:36
000002DABF  2020-09-12 03:48:46
000002DABG  2020-09-12 03:48:47
000002DABH  2020-09-12 03:48:50
000002DABI  2020-09-12 03:49:06
000002DABJ  2020-09-12 03:49:06
000002DABK  2020-09-12 03:49:09
000002DABL  2020-09-12 03:49:19
000002DABM  2020-09-12 03:49:20
000002DABN  2020-09-12 03:49:24
000002DABO  2020-09-12 03:49:33
000002DABP  2020-09-12 03:49:34
000002DABQ  2020-09-12 03:49:37
000002DABR  2020-09-12 03:49:48
000002DABS  2020-09-12 03:49:48
000002DABT  2020-09-12 03:49:51
000002DABU  2020-09-12 03:50:01
000002DABV  2020-09-12 03:50:01
000002DABW  2020-09-12 03:50:05
000002DABX  2020-09-12 03:50:15
000002DABY  2020-09-12 03:50:15
000002DABZ  2020-09-12 03:50:18
000002DAB0  2020-09-12 03:46:23 <-
000002DAB1  2020-09-12 03:46:24
000002DAB2  2020-09-12 03:46:28
000002DAB3  2020-09-12 03:47:18
000002DAB4  2020-09-12 03:47:18

Как видите, запрос упорядочивает от А до Я, затем от 0 до 9, но он должен упорядочивать от 0 до 9, затем от А до Я.

Есть ли способ установить строку, чтобы правильно ее упорядочить?

Что ж, мы не видим вашего запроса, так как вы ожидаете, что мы вам поможем? Вы должны по крайней мере скопировать и вставить предложение ORDER BY из вашего запроса.

user5683823 09.12.2020 19:34

Что вы получаете, когда бегаете select parameter, value from v$nls_parameters WHERE parameter IN ( 'NLS_LANGUAGE', 'NLS_SORT');? Эффект ORDER BY зависит от этих параметров.

trincot 09.12.2020 19:44

Тринкот (вверху) делает отличное замечание. Во французском, например, буквы сортируются перед цифрами. Это первое место, где нужно искать объяснение.

user5683823 09.12.2020 20:30

@mathguy Извините, я забыл упомянуть, я думал, что это не имеет значения. Я использую чистый обычный: ORDER BY TRN_ID Я сделал это, потому что есть некоторые данные, которые сохраняются в ту же секунду, и база данных не дает мне миллисекунд для их сортировки.

Kurt Costa Peters 12.12.2020 03:04

@trincot Я попробую ваше решение в понедельник, как только вернусь к работе! Я дам вам знать! Я верю, что это может помочь, как упомянул @mathguy!

Kurt Costa Peters 12.12.2020 03:08

Тринкот не предложил решения — он лишь предложил возможную причину того, что вы видите. Решение подскажет вам, что делать с проблемой — как обойти проблему, которая определена как причина вашей проблемы.

user5683823 12.12.2020 04:11
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
6
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Весьма вероятно, что наблюдение Тринкота (второй комментарий к вашему вопросу) верно: вы видите упорядочение по возрастанию с буквами перед цифрами (а не наоборот), потому что этого требует ваша сортировка.

Судя по вашему профилю, я предполагаю, что вы находитесь в Бразилии, и ваш параметр NLS_LANGUAGE равен 'BRAZILIAN PORTUGUESE', а параметр NLS_SORT по умолчанию (производный от NLS_LANGUAGE) равен 'WEST_EUROPEAN'. Это не выбор Oracle; В бразильской португальской сортировке (или, точнее, в западноевропейской сортировке) цифры стоят после букв, а не перед ними. См. демо в конце этого ответа.

Итак, это объясняет проблему. Как это исправить?

Если у вас много похожих запросов, и вы должны показывать цифры перед буквами во всех из них (или если у вас есть ORDER BY во многих местах в запросе - например, в аналитических функциях, или в match_recognize и т. д.), то это делает смысла менять параметр NLS_SORT для сеанса, с

alter session set nls_sort='BINARY';

Если вам нужно сделать это только в одном запросе, в предложении ORDER BY, вы можете просто изменить порядок сортировки локально (только для этого предложения ORDER BY, не затрагивая ничего другого) с помощью функции NLSSORT. Так:

.... order by nlssort(TRN_ID, 'NLS_SORT=BINARY')

Вот краткая демонстрация.

Во-первых, в моей системе NLS_LANGUAGE — это 'AMERICAN', а по умолчанию NLS_SORT (для этого языка) — 'BINARY'. Вот почему буквы идут после цифр:

select col
from   (select 'A' as col from dual union all select '3' from dual)
order  by col;

COL
---
3
A

Теперь позвольте мне изменить мой NLS_LANGUAGE на 'BRAZILIAN PORTUGUESE'. Затем давайте посмотрим, как это повлияло на NLS_SORT (автоматически) и как это повлияло на запрос:

alter session set nls_language='BRAZILIAN PORTUGUESE';

select parameter, value
from   v$nls_parameters
where  parameter in ('NLS_LANGUAGE', 'NLS_SORT');

PARAMETER    VALUE                 
------------ ----------------------
NLS_LANGUAGE BRAZILIAN PORTUGUESE  
NLS_SORT     WEST_EUROPEAN       



select col
from   (select 'A' as col from dual union all select '3' from dual)
order  by col;

COL
---
A
3

Теперь, не меняя языка, позвольте мне просто изменить последовательность сопоставления (параметр NLS_SORT) на 'BINARY' — и посмотреть, как запрос выдает желаемый результат. Мы не меняли язык, но мы изменили последовательность сопоставления для всего сеанса. Это будет работать для всех других запросов в текущем сеансе.

alter session set nls_sort='BINARY';

select parameter, value
from   v$nls_parameters
where  parameter in ('NLS_LANGUAGE', 'NLS_SORT');

PARAMETER    VALUE                 
------------ ----------------------
NLS_LANGUAGE BRAZILIAN PORTUGUESE  
NLS_SORT     BINARY 




select col
from   (select 'A' as col from dual union all select '3' from dual)
order  by col;

COL
---
3
A   

Наконец, позвольте мне изменить NLS_SORT обратно на 'WEST_EUROPEAN' и использовать функцию NLSSORT в предложении ORDER BY запроса, чтобы получить тот же результат (тот, который вам нужен), не касаясь параметров сеанса.

alter session set nls_sort='WEST_EUROPEAN';

select col
from   (select 'A' as col from dual union all select '3' from dual)
order  by col;   -- This will produce the wrong order! See below for fix.

COL
---
A
3  

select col
from   (select 'A' as col from dual union all select '3' from dual)
order  by nlssort(col, 'nls_sort=BINARY');

COL
---
3
A

Другие вопросы по теме