具有ORDER BY NULL的LISTAGG实际上使用什么作为订单标准?

MT0*_*MT0 13 oracle sql-order-by listagg

如果我做

SELECT LISTAGG( COLUMN_VALUE ) WITHIN GROUP ( ORDER BY NULL )   AS OrderByNULL,
       LISTAGG( COLUMN_VALUE ) WITHIN GROUP ( ORDER BY 1 )      AS OrderByCONST,
       LISTAGG( COLUMN_VALUE ) WITHIN GROUP ( ORDER BY ROWNUM ) AS OrderByROWNUM
FROM   TABLE( SYS.ODCIVARCHAR2LIST( '5', '222', '4' ) );
Run Code Online (Sandbox Code Playgroud)

输出是:

ORDERBYNULL ORDERBYCONST ORDERBYROWNUM
----------- ------------ -------------
222,4,5     222,4,5      5,222,4
Run Code Online (Sandbox Code Playgroud)

当使用ORDER BY非确定性排序(NULL或常量)时,查询似乎已完成字母数字排序,并在使用ORDER BY ROWNUM(确定性)时保持输入顺序.

LISTAGG文件指出:

order_by_clause确定返回连接值的顺序.仅当ORDER BY列列表实现唯一排序时,该函数才是确定性的.

在查看分析函数时,它指出:

每当order_by_clause为多行产生相同的值时,该函数的行为如下:[...]对于所有其他分析函数,结果取决于窗口规范.如果使用RANGE关键字指定逻辑窗口,则该函数会为每个行返回相同的结果.如果使用ROWS关键字指定物理窗口,则结果是不确定的.

因此,据我所知,从文档中可以看出非确定性排序 - 但是,该函数根据字母数字排序而不是处理行的顺序(这是常见的)提供确定性输出视图).

这与其他分析函数的行为不同(当使用带有ROWS关键字的物理窗口时):

SELECT LAST_VALUE( COLUMN_VALUE )
         OVER ( ORDER BY NULL   ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING )
         AS BYNULL,
       LAST_VALUE( COLUMN_VALUE )
         OVER ( ORDER BY 1      ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING )
         AS BYCONST,
       LAST_VALUE( COLUMN_VALUE )
         OVER ( ORDER BY ROWNUM ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING )
         AS BYROWNUM
FROM   TABLE( SYS.ODCIVARCHAR2LIST( '5', '222', '4' ) );
Run Code Online (Sandbox Code Playgroud)

这为所有不同的排序提供了一致的输出:

BYNULL BYCONST BYROWNUM
------ ------- --------
4      4       4
4      4       4
4      4       4
Run Code Online (Sandbox Code Playgroud)

是否有关于如何在LISTAGG提供非确定性排序时应用排序的官方文档?

注意:此处的ORDER BY NULL注释行为表示:

在此示例中,尽管存在NULL排序子句,但元素已按字母顺序聚合.这似乎是使用常量ORDER BY表达式时的默认行为

但这只是对非Oracle站点中的行为的评论.

mic*_*sca 1

顺序可能取决于许多因素,包括查询的执行计划、实例的配置、数据库的版本(无论您是否使用 Exadata)。

如果您没有向 Oracle 提供任何特定的标准来对数据进行排序,那么您就不能依赖任何特定的排序,即使从您的试验中您似乎得到了以特定方式一致排序的数据。

根据Oracle 的 listagg 文档

  • order_by_clause 确定返回连接值的顺序。仅当 ORDER BY 列列表实现唯一排序时,该函数才是确定性的。