2014-01-07 4 views
7

Die meisten Datenbanken haben eine eingebaute Funktion zur Berechnung des Median, aber ich sehe nichts für den Median in Amazon Redshift.Wie berechnet man den Median in AWS Redshift?

Sie könnten den Median mit einer Kombination der analytischen Funktionen nth_value() und count() berechnen, aber das scheint Janky zu sein. Ich wäre sehr überrascht, wenn eine Analytics-Datenbank keine integrierte Methode zur Berechnung des Medians hätte, also gehe ich davon aus, dass ich etwas verpasse.

http://docs.aws.amazon.com/redshift/latest/dg/r_Examples_of_NTH_WF.html http://docs.aws.amazon.com/redshift/latest/dg/c_Window_functions.html

Antwort

5

Und wie von 2014.10.17, unterstützt Redshift die MEDIAN Fensterfunktion:

# select min(median) from (select median(num) over() from temp); 
min 
----- 
4.0 
+0

Bessere Antwort verbunden – Keith

+0

wählen Sie distinkte Median (Feld) über() aus Tabelle –

4

Versuchen Sie, die NTILE Funktion.

Sie würden Ihre Daten in 2 Gruppen aufteilen und wählen Sie den Mindestwert aus der ersten Gruppe. Das liegt daran, dass in Datensätzen mit einer ungeraden Anzahl von Werten das erste ntile einen Wert mehr als das zweite hat. Diese Approximation sollte für große Datensätze sehr gut funktionieren.

create table temp (num smallint); 
insert into temp values (1),(5),(10),(2),(4); 

select num, ntile(2) over(order by num desc) from temp ; 
num | ntile 
-----+------- 
    10 |  1 
    5 |  1 
    4 |  1 
    2 |  2 
    1 |  2 

select min(num) as median from (select num, ntile(2) over(order by num desc) from temp) where ntile = 1; 
median 
-------- 
     4 
+0

dies als akzeptierte Antwort Kennzeichnung, da es scheint, wie es in der Theorie funktionieren soll, aber ich habe nicht wirklich getestet . Gute Idee! – tayl0rs

0

ich verwende in der Regel die NTILE Funktion die Daten in zwei Gruppen zu teilen, wenn ich auf eine Antwort bin auf der Suche, die nahe genug ist. Wenn ich jedoch den genauen Median (z. B. den Mittelpunkt einer geraden Reihe von Reihen) haben möchte, verwende ich eine Technik, die auf der AWS Redshift Discussion Forum vorgeschlagen wird.

Bei dieser Technik werden die Zeilen sowohl in aufsteigender als auch in absteigender Reihenfolge angeordnet. Bei einer ungeraden Anzahl von Zeilen wird der Durchschnitt der mittleren Zeile (dh row_num_asc = row_num_desc) zurückgegeben, die einfach die mittlere Zeile ist selbst.

CREATE TABLE temp (num SMALLINT); 

INSERT INTO temp VALUES (1),(5),(10),(2),(4); 

SELECT 
    AVG(num) AS median 
FROM 
(SELECT 
    num, 
    SUM(1) OVER (ORDER BY num ASC) AS row_num_asc, 
    SUM(1) OVER (ORDER BY num DESC) AS row_num_desc 
FROM 
    temp) AS ordered 
WHERE 
    row_num_asc IN (row_num_desc, row_num_desc - 1, row_num_desc + 1); 

median 
-------- 
     4 

Wenn eine gerade Anzahl von Zeilen vorhanden ist, wird der Durchschnitt der beiden mittleren Zeilen zurückgegeben.

INSERT INTO temp VALUES (9); 

SELECT 
    AVG(num) AS median 
FROM 
(SELECT 
    num, 
    SUM(1) OVER (ORDER BY num ASC) AS row_num_asc, 
    SUM(1) OVER (ORDER BY num DESC) AS row_num_desc 
FROM 
    temp) AS ordered 
WHERE 
    row_num_asc IN (row_num_desc, row_num_desc - 1, row_num_desc + 1); 

median 
-------- 
    4.5 
1

Ich hatte Schwierigkeiten mit diesem auch, aber bekam Hilfe von Amazon. Seit der Version 2014-06-30 von Redshift können Sie dies mit den Fensterfunktionen PERCENTILE_CONT oder PERCENTILE_DISC tun.

Sie sind etwas komisch zu verwenden, wie sie den Median (oder was auch immer Prozent wählen Sie) auf jede Reihe. Sie legen das in eine Unterabfrage und nehmen dann die MIN (oder was auch immer) der mittleren Spalte.

# select count(num), min(median) as median from (select num, percentile_cont (0.5) within group (order by num) over() as median from temp); count | median -------+-------- 5 | 4.0

(Der Grund ist es kompliziert ist, dass Fensterfunktionen auch ihre eigenen tun können Mini-group-by und Bestellung Sie den Median von vielen Gruppen auf einmal zu geben, und andere Tricks.)

Im Fall einer geraden Anzahl von Werten interpoliert CONT (inuous) zwischen den beiden mittleren Werten, wobei DISC (rete) eine davon auswählt.