我有这个问题:
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
有人可以解释为什么我得到这些结果?我该如何解决这个问题?
你似乎正在使用linguistic sorting and matching,无论你的会话中设置的NLS_SORT
- 或者可能是column-level collation设置 - 都会让你遇到ignorable characters。
在我的默认会话中,我看不到与您相同:
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
但这仍然将*
价值放在第一位。
您可能必须使用案例表达式来修复:
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
我有一个框架,根据GUI中的boutton将ASC或DESC附加到自定义查询中,我无法触及框架以使其更改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
您可以使用:
select ID_USER, NUMERO, NOM
from user_view
WHERE UPPER(NOM) = 'JACKSON'
order by replace(numero,'*','')