sql >> Databasteknik >  >> RDS >> Oracle

Villkorlig ordning efter klausul

Detta verkar vara bugg 5695629, som verkar ha höjts mot 10g och inte verkar ha åtgärdats ännu (från 12cR2; jag har inte 18 att spela med ännu), vilket är ovanligt.

Du kan undvika det genom att slå in frågan i ett yttre urval innan du beställer:

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 ;

Men som name och marks är (förmodligen) olika datatyper - sträng och nummer - som istället får

Du kan konvertera marks till en sträng, men om du gör det måste du fylla på den så att sorteringen av den resulterande strängen alfabetiskt stämmer överens med den numeriska ordningen - rörigt men troligt eftersom märkena (återigen, förmodligen - om det är en procentandel?) bara kan vara upp till tre siffror :

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<>fioldemo använda vissa dummydata som tillhandahålls via CTE.

Om markeringarna kan vara fler än tre siffror ändrar du formatmasken så att den matchar maximalt möjliga längd.

TO_CHAR('NULL') del är också udda eftersom det ger dig den bokstavliga strängen "NULL" i namnkolumnen för dessa rader. Eftersom du börjar med en bokstavlig sträng är TO_CHAR() del är meningslös, använd bara 'NULL' AS name direkt. Om du verkligen vill att det ska vara tomt kan du bara använda null AS name och det kommer att matcha datatypen för det matchande kolumnuttrycket från den första grenen av föreningen (och kommer också att ta upp dess alias). Du kan uttryckligen casta till en strängtyp, t.ex. cast(null as varchar2(20)) AS name men det verkar inte vara så mycket mening.



  1. postgres:hitta alla heltalskolumner med dess nuvarande maxvärde i

  2. Hur skapar man någon form av iterator (eller artificiell id) för en given uppsättning rader?

  3. Hur man får kolumnvärden i ett kommaseparerat värde

  4. Installera PostgreSQL på Ubuntu för Ruby on Rails