sql >> Database >  >> RDS >> Oracle

Voorwaardelijke volgorde per clausule

Dit lijkt bug 5695629 te zijn, die lijkt te zijn verhoogd tegen 10g en nog niet lijkt te zijn opgelost (vanaf 12cR2; ik heb er nog geen 18 om mee te spelen), wat ongebruikelijk is.

U kunt dit voorkomen door de zoekopdracht in een buitenste selectie te plaatsen voordat u bestelt:

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 ;

Maar als name en marks zijn (vermoedelijk) verschillende gegevenstypen - tekenreeks en getal - die in plaats daarvan

. krijgen

Je zou marks kunnen converteren naar een tekenreeks, maar als u dat doet, moet u deze opvullen, zodat het alfabetisch sorteren van de resulterende tekenreeks nog steeds overeenkomt met de numerieke volgorde - rommelig maar aannemelijk omdat de markeringen (nogmaals, vermoedelijk - als het een percentage is?) maximaal drie cijfers kunnen bevatten :

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<>fiddle-demo met behulp van enkele dummy-gegevens die via CTE's worden geleverd.

Als de markeringen meer dan drie cijfers kunnen zijn, verander dan het formaatmasker zodat het overeenkomt met de maximaal mogelijke lengte.

De TO_CHAR('NULL') deel is ook vreemd, want dat geeft je de letterlijke tekenreeks "NULL" in de naamkolom voor die rijen. Aangezien je begint met een letterlijke tekenreeks, is de TO_CHAR() deel is zinloos, gebruik gewoon 'NULL' AS name direct. Als je echt wilt dat het leeg is, kun je gewoon null AS name gebruiken en het zal overeenkomen met het gegevenstype van de overeenkomende kolomuitdrukking van de eerste tak van de unie (en zal ook zijn alias ophalen). Je zou expliciet naar een stringtype kunnen casten, b.v. cast(null as varchar2(20)) AS name maar het lijkt niet veel zin te hebben.



  1. Entiteiten genereren uit database

  2. invoegen in... selecteer ... met subquery of zonder kolomvolgorde

  3. Migratiefout in django 2; AttributeError:'str' object heeft geen attribuut 'decode'

  4. Oplossing van deze gemakkelijke trigger