oracle 对简单排序方式和 listagg 排序方式的排序方式不同

oracle sorts differently on simple order by and listagg's order by

Oracle Database 19c 标准版 2 发行版 19.0.0.0.0 - 生产

select letter from (
select 'A' as letter from dual union all
select 'Á' as letter from dual union all
select 'B' as letter from dual union all
select 'C' as letter from dual ) t
order by letter;

结果(没问题):

A
Á
B
C

但是有了这个

select listagg(letter,', ') within group (order by letter) from (
select 'A' as letter from dual union all
select 'Á' as letter from dual union all
select 'B' as letter from dual union all
select 'C' as letter from dual ) t;

结果字母顺序不同:

A, B, C, Á

后一种情况是简单的 Oracle 错误吗?

(我没有说任何关于 NLS 的事情。我认为这些查询应该独立于 NLS 以相同的方式工作。)

更新:

澄清: 我在同一个连接中 运行 在 SqlDeveloper 中一个接一个地查询这些查询。

NLS_SORT    HUNGARIAN
NLS_COMP    BINARY

(如果@MT0 的回答是解决方案,那么恕我直言,这是 oracle 中的一个错误,在简单的 order by 子句和 listagg 调用上使用不同的默认 NLS 设置。)

字母的顺序主要取决于 NLS_SORT,所以您在邮件末尾所说的是完全错误的。

主要问题是 - 您是否在具有所有相同 NLS 设置的完全相同的系统上得到了那些相互矛盾的结果?如果是这样,那就是 LISTAGGORDER BY 子句的实现中的错误。最好有一个测试用例 - 向我们展示您的 NLS 设置(select * from v$nls_parameters 的结果),紧接着是两个查询及其输出。为了更好地衡量,还显示 select * from v$version(告诉我们您的数据库版本)。

您需要提供 NLS_SORT 设置:

select listagg(letter,', ')
       within group (order by NLSSORT(letter, 'NLS_SORT=BINARY_AI')) AS letters
from (
  select 'A' as letter from dual union all
  select 'Á' as letter from dual union all
  select 'B' as letter from dual union all
  select 'C' as letter from dual
) t;

输出:

LETTERS
A, Á, B, C

注意:LISTAGG 似乎没有在其 ORDER BY 子句中使用会话 NLS_SORT 设置;但是你可以像上图那样直接传入

如果要使用会话参数(而不是特定值):

select listagg(letter,', ')
       within group (
         order by NLSSORT(
                    letter,
                    ( SELECT 'NLS_SORT='||value
                      FROM   NLS_SESSION_PARAMETERS
                      WHERE  parameter = 'NLS_SORT' )
                  )
       ) AS letters
from (
  select 'A' as letter from dual union all
  select 'Á' as letter from dual union all
  select 'B' as letter from dual union all
  select 'C' as letter from dual
) t;

db<>fiddle here