2017-05-03 3 views
0

Ich habe eine Case Aussage, die mir Werte liegen im Bereich geben wird. Ich brauche das Ergebnis dementsprechend in Bereich weise gesetzt, um zu sortieren:Sorting Bereichswerte in Oracle SQL

select distinct CASE 
    when Table__107.Column <= 30 then 
     '0-30' 
    when (Table__107.Column >= 31 and 
      Table__107.Column <= 60) then 
     '31-60' 
    when (Table__107.Column >= 61 and 
      Table__107.Column <= 90) then 
     '61-90' 
    when (Table__107.Column >= 91 and 
      Table__107.Column <= 120) then 
     '91-120' 
    when (Table__107.Column >= 121 and 
      Table__107.Column <= 180) then 
     '121-180' 
    when (Table__107.Column >= 181 and 
      Table__107.Column <= 365) then 
     '181-365' 
    when Table__107.Column > 365 then 
     '365+' 
    end as Column 

Meine erforderliche Ausgabe ist

0-30 
31-60 
61-90 
..... 
..... 
365+ 

Flagge

Ich versuchte Order by 1 und Order By ASC verwenden, aber es ist die Sortierung auf Basis von ersten Zeichen alphanumerisch nicht numerischer Wert des Bereichs.

+0

ich versuchte ORDER BY 1 und Sortieren von ASC verwenden, aber es basierend auf ersten Zeichen zu sortieren. – user1838000

Antwort

1

Erstens könnten Sie Ihre Bereiche umbenennen sortierbar zu sein. . . 000-030, '031-060', und so weiter. Dann können Sie direkt nach dem Wert bestellen.

Als nächstes können Sie die Logik vereinfachen, weil Sie wissen, dass die Case-Bedingungen, um ausgewertet werden.

Schließlich können Sie bekommen, was Sie group by verwenden mögen und dann anschliessend die Bestellung, etwa durch den Minimalwert in jeder Gruppe:

select (case when Table__107.Column <= 30 then '0-30' 
      when Table__107.Column <= 60 then '31-60' 
      when Table__107.Column <= 90 then '61-90' 
      when Table__107.Column <= 120 then '91-120' 
      when Table__107.Column <= 180 then '121-180' 
      when Table__107.Column <= 365 then '181-365' 
      when Table__107.Column > 365 then '365+' 
     end) as Column, 
     count(*) -- this is a guess 
from t 
group by (case when Table__107.Column <= 30 then '0-30' 
       when Table__107.Column <= 60 then '31-60' 
       when Table__107.Column <= 90 then '61-90' 
       when Table__107.Column <= 120 then '91-120' 
       when Table__107.Column <= 180 then '121-180' 
       when Table__107.Column <= 365 then '181-365' 
       when Table__107.Column > 365 then '365+' 
      end) 
order by min(Table__107.Column); 
2

Gerade zweite Spalte erstellen - mit gleichen Kriterien (Fällen), aber mit der Bestellnummer und dann nach dieser Spalte sortieren.

Etwas wie folgt aus:

select distinct CASE 
    when Table__107.Col <= 30 then 
     '0-30' 
    when (Table__107.Col >= 31 and 
      Table__107.Col <= 60) then 
     '31-60' 
    when (Table__107.Col >= 61 and 
      Table__107.Col <= 90) then 
     '61-90' 
    when (Table__107.Col >= 91 and 
      Table__107.Col <= 120) then 
     '91-120' 
    when (Table__107.Col >= 121 and 
      Table__107.Col <= 180) then 
     '121-180' 
    when (Table__107.Col >= 181 and 
      Table__107.Col <= 365) then 
     '181-365' 
    when Table__107.Col > 365 then 
     '365+' 
    end as Col, CASE 
    when Table__107.Col <= 30 then 
     1 
    when (Table__107.Col >= 31 and 
      Table__107.Col <= 60) then 
     2 
    when (Table__107.Col >= 61 and 
      Table__107.Col <= 90) then 
     3 
    when (Table__107.Col >= 91 and 
      Table__107.Col <= 120) then 
     4 
    when (Table__107.Col >= 121 and 
      Table__107.Col <= 180) then 
     5 
    when (Table__107.Col >= 181 and 
      Table__107.Col <= 365) then 
     6 
    when Table__107.Col > 365 then 
     7 end as ord 
    from Table__107 
    order by ord 
+0

Doppelte Logik ist hässlich – APC

2

Zeit Eimer scheinen, wie die Art von Daten, die eine Referenzdatentabelle verdienen. Aber selbst wenn Sie keine Tabelle für sie erstellen möchten, gibt es Vorteile, sie als eine Einheit zu behandeln.

Bei dieser Lösung verwende ich die WITH-Klausel eine Unterabfrage mit einer Sortiernummer, unterer und oberer Grenze, und ein Etikett für jedes Zeitband zu erstellen. Dadurch macht zählen es leicht zu (sagen wir), wie Fälle von Table__107.col1 Rückgang auf jedem Eimer:

with buckets as ( 
    select 1 as bno, 0 as lb, 30 as ub, '0-30' as label from dual union all 
    select 2 as bno, 31 as lb, 60 as ub, '31-60' as label from dual union all 
    select 3 as bno, 61 as lb, 90 as ub, '61-90' as label from dual union all 
    select 4 as bno, 91 as lb, 120 as ub, '91-120' as label from dual union all 
    select 5 as bno, 121 as lb, 180 as ub, '121-180' as label from dual union all 
    select 6 as bno, 181 as lb, 365 as ub, '181-365' as label from dual union all 
    select 7 as bno, 365 as lb, 10000 as ub, '365+' as label from dual) 
select count(t107.col1) as col1_cnt 
     , b.label as bucket 
from buckets b 
     left outer join Table__107 t107 
      on t107.col1 between b.lb and b.ub 
group by b.bno, b.label 
order by b.bno  ; 

gibt es keine Notwendigkeit, die Logik zu duplizieren. Ein weiterer Vorteil ist, dass wir einen äußeren Join verwenden können und leere Buckets erfassen können.