sql >> Base de Datos >  >> RDS >> Oracle

Orden condicional por cláusula

Este parece ser el error 5695629, que parece haberse planteado contra 10g y no parece haberse solucionado todavía (a partir de 12cR2; todavía no tengo 18 para jugar), lo cual es inusual.

Puede evitarlo envolviendo la consulta en una selección externa antes de realizar el 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 ;

Pero como name y marks son (presumiblemente) diferentes tipos de datos (cadena y número) que obtendrán

Podrías convertir marks a una cadena, pero si lo hace, debe rellenarlo para que ordenar la cadena resultante alfabéticamente aún coincida con el orden numérico, complicado pero plausible ya que las marcas pueden (de nuevo, presumiblemente, ¿si es un porcentaje?) solo tener hasta tres dígitos :

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<>demostración de violín utilizando algunos datos ficticios suministrados a través de CTE.

Si las marcas pueden tener más de tres dígitos, cambie la máscara de formato para que coincida con la longitud máxima posible.

El TO_CHAR('NULL') part también es extraño ya que le dará la cadena literal "NULL" en la columna de nombre para esas filas. Dado que comienza con un literal de cadena, el TO_CHAR() parte no tiene sentido, solo use 'NULL' AS name directamente. Si realmente desea que esté en blanco, puede usar null AS name y coincidirá con el tipo de datos de la expresión de columna coincidente de la primera rama de la unión (y también recogerá su alias). Podría convertir explícitamente a un tipo de cadena, p. cast(null as varchar2(20)) AS name pero no parece tener mucho sentido.