Заказ Oracle по неожиданному результату - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть этот запрос:

SELECT DISTINCT 
ID_USER, 
NUMERO, -- VARCHAR2(8 BYTE) 
NOM
FROM USER_VIEW 
WHERE UPPER(NOM) = 'JACKSON'
ORDER BY NUMERO ASC

Я ожидаю, что результаты будут такими:

ID_USER  |   NUMERO   |   NOM
--------------------------------
1        |   TI33     |  JACKSON
9        |   TI99     |  JACKSON
4        |   1999     |  JACKSON
0        |   2001     |  JACKSON
3        |   2006     |  JACKSON
8        |   *04      |  JACKSON
5        |   *15      |  JACKSON
7        |   *61      |  JACKSON

, но я получаю нежелательные результаты:

ID_USER  |   NUMERO   |   NOM
--------------------------------
1        |   TI33     |  JACKSON
9        |   TI99     |  JACKSON
8        |   *04      |  JACKSON
5        |   *15      |  JACKSON
4        |   1999     |  JACKSON
0        |   2001     |  JACKSON
3        |   2006     |  JACKSON
7        |   *61      |  JACKSON

Может кто-нибудь объяснить, почему я получаю эти результаты?и как я могу это исправить?

Ответы [ 2 ]

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

Вы, похоже, используете лингвистическую сортировку и сопоставление , и все, что NLS_SORT установлено в вашем сеансе - или, возможно, параметр сопоставление на уровне столбца - заставляет васвстреча игнорируемых символов .

В моем сеансе по умолчанию я не вижу того же, что и вы:

alter session set nls_sort = binary;
alter session set nls_comp = binary;

with user_view (id_user, numero, nom) as (
  select 1, cast('TI33' as varchar2(8 byte)), 'JACKSON' from dual
  union all select 9, 'TI99', 'JACKSON' from dual
  union all select 4, '1999', 'JACKSON' from dual
  union all select 0, '2001', 'JACKSON' from dual
  union all select 3, '2006', 'JACKSON' from dual
  union all select 8, '*04', 'JACKSON' from dual
  union all select 5, '*15', 'JACKSON' from dual
  union all select 7, '*61', 'JACKSON' from dual
)
SELECT DISTINCT 
ID_USER, 
NUMERO,
NOM
FROM USER_VIEW 
WHERE UPPER(NOM) = 'JACKSON'
ORDER BY NUMERO ASC
/

   ID_USER NUMERO   NOM    
---------- -------- -------
         8 *04      JACKSON
         5 *15      JACKSON
         7 *61      JACKSON
         4 1999     JACKSON
         0 2001     JACKSON
         3 2006     JACKSON
         1 TI33     JACKSON
         9 TI99     JACKSON

Если я изменю настройки (выбираю язык наугад) затем я делаю:

alter session set nls_sort = spanish_ci;
alter session set nls_comp = linguistic;

...

   ID_USER NUMERO   NOM    
---------- -------- -------
         1 TI33     JACKSON
         9 TI99     JACKSON
         8 *04      JACKSON
         5 *15      JACKSON
         4 1999     JACKSON
         0 2001     JACKSON
         3 2006     JACKSON
         7 *61      JACKSON

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

SELECT DISTINCT 
ID_USER, 
NUMERO,
NOM
FROM USER_VIEW 
WHERE UPPER(NOM) = 'JACKSON'
ORDER BY nlssort(NUMERO, 'NLS_SORT=BINARY') ASC
/

   ID_USER NUMERO   NOM    
---------- -------- -------
         8 *04      JACKSON
         5 *15      JACKSON
         7 *61      JACKSON
         4 1999     JACKSON
         0 2001     JACKSON
         3 2006     JACKSON
         1 TI33     JACKSON
         9 TI99     JACKSON

, но это все равно ставит *Сначала 1020 * значений.

Возможно, вам придется использовать выражение case, чтобы исправить это:

SELECT DISTINCT 
ID_USER, 
NUMERO,
NOM
FROM USER_VIEW 
WHERE UPPER(NOM) = 'JACKSON'
ORDER BY CASE WHEN SUBSTR(NUMERO, 1, 1) = '*' then 2 else 1 end, NUMERO
/

   ID_USER NUMERO   NOM    
---------- -------- -------
         1 TI33     JACKSON
         9 TI99     JACKSON
         4 1999     JACKSON
         0 2001     JACKSON
         3 2006     JACKSON
         8 *04      JACKSON
         5 *15      JACKSON
         7 *61      JACKSON

У меня есть структура, которая добавляет ASC или DESC к пользовательскому запросу в зависимости откнопка в графическом интерфейсе, и я не могу дотронуться до каркаса, чтобы он изменил значения в выражении case также

Затем вы можете объединить результат выражения case (как строку, а не числа, с любыми символами)которые находятся в правильном порядке в васг сопоставление действительно);при заказе по одному комбинированному выражению вы можете упорядочить по возрастанию:

SELECT DISTINCT 
ID_USER, 
NUMERO,
NOM
FROM USER_VIEW 
WHERE UPPER(NOM) = 'JACKSON'
ORDER BY CASE WHEN SUBSTR(NUMERO, 1, 1) = '*' then 'B' else 'A' end || NUMERO ASC
/

   ID_USER NUMERO   NOM    
---------- -------- -------
         1 TI33     JACKSON
         9 TI99     JACKSON
         4 1999     JACKSON
         0 2001     JACKSON
         3 2006     JACKSON
         8 *04      JACKSON
         5 *15      JACKSON
         7 *61      JACKSON

... или по убыванию:

SELECT DISTINCT 
ID_USER, 
NUMERO,
NOM
FROM USER_VIEW 
WHERE UPPER(NOM) = 'JACKSON'
ORDER BY CASE WHEN SUBSTR(NUMERO, 1, 1) = '*' then 'B' else 'A' end || NUMERO DESC
/

   ID_USER NUMERO   NOM    
---------- -------- -------
         7 *61      JACKSON
         5 *15      JACKSON
         8 *04      JACKSON
         3 2006     JACKSON
         0 2001     JACKSON
         4 1999     JACKSON
         9 TI99     JACKSON
         1 TI33     JACKSON
0 голосов
/ 21 февраля 2019

Вы можете использовать:

select ID_USER, NUMERO, NOM 
from user_view
WHERE UPPER(NOM) = 'JACKSON'
order by replace(numero,'*','')
...