Se faccioCosa utilizza LISTAGG con ORDER BY NULL come criterio dell'ordine?
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'));
Il risultato è:
ORDERBYNULL ORDERBYCONST ORDERBYROWNUM
----------- ------------ -------------
222,4,5 222,4,5 5,222,4
La query sembra aver fatto un ordinamento alfanumerico utilizzando ORDER BY
con ordine non deterministico (NULL
o una costante) e ha mantenuto la ordine di input quando si utilizza ORDER BY ROWNUM
(deterministico).
La documentazione LISTAGG
afferma che:
L'order_by_clause determina l'ordine in cui vengono restituiti i valori concatenati. La funzione è deterministica solo se l'elenco di colonne ORDER BY ha ottenuto un ordinamento univoco.
E quando guardando analytic functions si afferma che:
Ogni volta che i risultati order_by_clause nei valori identici per più righe, la funzione si comporta come segue: [...] Per tutte le altre funzioni analitiche, la il risultato dipende dalle specifiche della finestra. Se si specifica una finestra logica con la parola chiave RANGE, la funzione restituisce lo stesso risultato per ciascuna delle righe. Se si specifica una finestra fisica con la parola chiave ROWS, il risultato non è deterministico.
Quindi, per quanto posso dire dalla documentazione un ordinamento non-deterministico è prevedibile - tuttavia, la funzione fornisce un'uscita deterministico sulla base di una sorta di testo e non l'ordine in cui vengono elaborate le righe (che è lo commonly held view).
Questo è diverso al comportamento di altre funzioni analitiche (quando si utilizza una finestra fisico con la parola chiave 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'));
che dà un risultato coerente per tutti i diversi ordinamenti:
BYNULL BYCONST BYROWNUM
------ ------- --------
4 4 4
4 4 4
4 4 4
Esiste documentazione ufficiale su come viene applicato un ordine quando a LISTAGG
viene fornito un ordinamento non deterministico?
Nota: Il comportamento di ORDER BY NULL
è commentato here affermando:
In questo esempio, gli elementi sono stati aggregati alfabetico, nonostante la clausola NULL ordinazione. Questo sembra essere il comportamento predefinito quando si utilizza un'espressione ORDER BY costante
Ma questo è solo un commento sul comportamento in un sito non Oracle.
Un insieme di risultati fornisce una prova praticamente nulla del determinismo. Se si utilizza una costante o 'NULL', quindi si aspettano i risultati in qualsiasi ordine. La documentazione è abbastanza chiara che non è possibile fare affidamento sull'ordinazione quando le chiavi 'order by' hanno gli stessi valori. –
Tuttavia, se si ripete il test (con dati diversi) si otterrà sempre lo stesso ordine alfanumerico. Di quanti set di risultati hai bisogno per questo ordine di essere considerato un elemento di design piuttosto che una coincidenza? – MT0
Qualunque cosa stia facendo sembra ignorare NLS_COMP/SORT. Presumibilmente è un dettaglio di implementazione. piuttosto che una caratteristica di design - e quindi non sembra essere documentato, anche su MOS. E come tale, non è qualcosa su cui puoi fare affidamento - dal momento che potrebbe cambiare in una versione futura? È interessante, ma non è sicuro se sia utile. –