Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Javascript Classificando um Array como order by no Oracle


Iirc, a Oracle implementa uma classificação lexicográfica de 3 camadas (mas siga o conselho de Alex Poole e verifique primeiro as configurações de NLS):
  • Primeiro classifique por caracteres básicos, ignorando maiúsculas e minúsculas e diacríticos, os dígitos vêm após as letras na sequência de intercalação.
  • Segundo, em empates ordenar respeitando diacríticos, ignorando maiúsculas.
  • Terceiro, em empates, classifique por caso.

Você pode emular o comportamento usando javascript locale apis imitando cada etapa em uma função de comparação personalizada, com exceção da inversão letra-dígito na sequência de agrupamento.

Enfrente o último identificando 10 pontos de código contíguos que não representam dígitos e que estão além do conjunto de pontos de código que podem ocorrer nas strings que você está classificando. Mapeie os dígitos na ordem de preservação do intervalo de pontos de código escolhido. Ao classificar, especifique a extensão de agrupamento Unicode 'direta', que significa 'classificação por ponto de código'. Remapear após a classificação.

No código PoC abaixo, escolhi alguns caracteres cirílicos.
function cmptiered(a,b) {
    //
    // aka oracle sort
    //
    return lc_base.compare(a, b) || lc_accent.compare(a, b) || lc_case.compare(a, b);
}  // cmptiered

var lc_accent   = new Intl.Collator('de', { sensitivity: 'accent' });
var lc_base     = new Intl.Collator('de-DE-u-co-direct', { sensitivity: 'base' });
var lc_case     = new Intl.Collator('de', { caseFirst: 'lower', sensitivity: 'variant' });

var array = ['Ba12nes','Apfel','Banane','banane','abc','ABC','123','2', null, 'ba998ne' ];

// Map onto substitute code blocks
array = array.map ( function ( item ) { return (item === null) ? null : item.replace ( /[0-9]/g, function (c) { return String.fromCharCode(c.charCodeAt(0) - "0".charCodeAt(0) + "\u0430".charCodeAt(0)); } ); } );

array.sort(cmptiered);

// Remap substitute code point
array = array.map ( function ( item ) { return (item === null) ? null : item.replace ( /[\u0430-\u0439]/g, function (c) { return String.fromCharCode(c.charCodeAt(0) - "\u0430".charCodeAt(0) + "0".charCodeAt(0)); } ); } );

Editar

Função cmptiered simplificado após o comentário de Nina Scholz.