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

Ordem condicional por cláusula


Este parece ser o bug 5695629, que parece ter sido aumentado contra 10g e não parece ter sido corrigido ainda (a partir de 12cR2; eu não tenho 18 para jogar ainda), o que é incomum.

Você pode evitá-lo envolvendo a consulta em uma seleção externa antes de fazer o pedido:
select name, grade, marks
from
(
    SELECT
        name, grade, marks
    FROM
        students, grades
    WHERE
        min_mark <= marks
        AND   marks <= max_mark
        AND   marks >= 70
    UNION
    SELECT
        TO_CHAR('NULL') AS name, grade, marks
    FROM
        students, grades
    WHERE
        min_mark <= marks
        AND   marks <= max_mark
        AND   marks <= 69
)
order by grade desc,case when grade >= 1 
                     then  name 
                     when grade < 1 
                     then  marks
                     end ;

Mas como name e marks são (presumivelmente) tipos de dados diferentes - string e número - que, em vez disso, obterão

Você pode converter marks para uma string, mas se você fizer isso, precisará preenchê-la para que a classificação da string resultante em ordem alfabética ainda corresponda à ordem numérica - confusa, mas plausível, pois as marcas podem (novamente, presumivelmente - se for uma porcentagem?) :
select name, grade, marks
from
(
    ...
    <the main part of your query here as a subquery, as above>
    ...
)
order by grade desc,case when grade >= 8 
                     then  name 
                     when grade < 8 
                     then  to_char(marks, 'FM000')
                     end ;

db<>demonstração de violino usando alguns dados fictícios fornecidos via CTEs.

Se as marcas puderem ter mais de três dígitos, altere a máscara de formato para corresponder ao comprimento máximo possível.

O TO_CHAR('NULL') part também é estranho, pois isso fornecerá a string literal "NULL" na coluna de nome dessas linhas. Como você começa com um literal de string, o TO_CHAR() parte é inútil, apenas use 'NULL' AS name diretamente. Se você realmente quiser que fique em branco, basta usar null AS name e ele corresponderá ao tipo de dados da expressão de coluna correspondente da primeira ramificação da união (e também selecionará seu alias). Você pode converter explicitamente para um tipo de string, por exemplo cast(null as varchar2(20)) AS name mas não parece haver muito sentido.