Was Sie suchen, ist im Grunde die Daten für eine histogram.
Sie hätten das Alter (oder Altersbereich) auf der X-Achse und den Zählwert n (oder die Häufigkeit) auf der Y-Achse.
In der einfachsten Form könnte man einfach die Anzahl der jede einzelne Alterswert zählen wie bereits beschrieben:
SELECT age, count(*)
FROM tbl
GROUP BY age
Wenn es jedoch zu viele unterschiedliche Werte für die x-Achse sind, um ein möchten Erstellen Sie Gruppen (oder Cluster oder Buckets). In Ihrem Fall gruppieren Sie mit einem konstanten Bereich von 10.
Wir können vermeiden, eine WHEN ... THEN
Zeile für jeden Bereich zu schreiben - es könnte Hunderte geben, wenn es nicht über Alter wäre. Stattdessen ist der Ansatz von @MatthewFlaschen aus den von @NitinMidha genannten Gründen vorzuziehen.
Nun wollen wir die SQL bauen ...
Zuerst müssen wir das Alter in Entfernungs-Gruppen von 10 wie so aufgeteilt:
Dies kann durch div erreicht werden Iding die Alte Spalte 10 und dann das Boden des Ergebnisses der Berechnung:
FLOOR(age/10)
„FLOOR auf die größte ganze Zahl zurückzugibt oder kleiner als n“ http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions067.htm#SQLRF00643
Dann nehmen wir den ursprünglichen SQL und ersetzen Alte mit diesem Ausdruck:
SELECT FLOOR(age/10), count(*)
FROM tbl
GROUP BY FLOOR(age/10)
das ist in Ordnung, aber wir können den Bereich nicht sehen, noch nicht. Stattdessen sehen wir nur die berechneten Bodenwerte, die 0, 1, 2 ... n
sind.
Um die tatsächliche untere Grenze zu erhalten, müssen wir es wieder mit 10 multiplizieren, so dass wir 0, 10, 20 ... n
erhalten:
FLOOR(age/10) * 10
Wir brauchen auch die oberen jeden Bereich gebunden, die gebunden + 10 niedriger ist - 1 oder
FLOOR(age/10) * 10 + 10 - 1
Schließlich verketten wir beide in eine Zeichenfolge wie folgt:
TO_CHAR(FLOOR(age/10) * 10) || '-' || TO_CHAR(FLOOR(age/10) * 10 + 10 - 1)
Dies erstellt '0-9', '10-19', '20-29'
usw.
Jetzt ist unsere SQL wie folgt aussieht:
SELECT
TO_CHAR(FLOOR(age/10) * 10) || ' - ' || TO_CHAR(FLOOR(age/10) * 10 + 10 - 1),
COUNT(*)
FROM tbl
GROUP BY FLOOR(age/10)
schließlich einen Auftrag und schöne Spaltenaliasnamen gelten:
SELECT
TO_CHAR(FLOOR(age/10) * 10) || ' - ' || TO_CHAR(FLOOR(age/10) * 10 + 10 - 1) AS range,
COUNT(*) AS frequency
FROM tbl
GROUP BY FLOOR(age/10)
ORDER BY FLOOR(age/10)
jedoch in komplexeren Szenarien, könnten diese Bereiche nicht in konstant gruppiert werden Stücke der Größe 10, müssen aber dynamisch gruppiert werden. Oracle hat erweiterte Histogrammfunktionen enthalten, siehe http://docs.oracle.com/cd/E16655_01/server.121/e15858/tgsql_histo.htm#TGSQL366
Dank an @MatthewFlaschen für seinen Ansatz; Ich habe nur die Details erklärt.
Dies sollte die erste und einzige Antwort auf diese Frage sein. Könnte etwas mehr Formatierung verwenden. – jva
Nein, CASE-Anweisungen verwenden Kurzschlussbewertung – Einstein
Wie würde eine Kurzschlussbewertung ein Problem in dieser Abfrage verursachen? Da die Fälle geordnet sind und <= verwenden, wird immer die richtige Gruppe ausgewählt. Ist es nicht? – Adrian