2017-10-24 3 views
0

ich eine Tabelle mit einer Liste von 499 positiven Nicht-Integer-Zahlen N haben, möchte ich den Median dieser Zahlen zu finden, und ich habe unter:SQL finden Median

SELECT (ROUND(N,4)) FROM TABLE ORDER BY N LIMIT 1 OFFSET ((COUNT(N)-1)/2); 

ich die folgende Fehlermeldung erhalten:

"ERROR 1064 (42000) at line 15: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '((COUNT(N)-1)/2)' at line 4"

Dies funktioniert, wenn ich ((COUNT(N)-1)/2) von (wo der Median wäre nach Tisch bestellt wird) ersetzen, so kann ich ((COUNT(N)-1)/2) nicht verwenden. Warum ist das? Was sollte ich stattdessen tun, um den Median zu finden?

Dank

+0

Es ist nicht möglich, das LIMIT als dynamische Zahl in einer Select-Abfrage zu definieren, siehe: https://Stackoverflow.com/a/5873705/2067753 –

Antwort

0

Es ist ein wenig komplex, benötigen Sie einen Index mit Ihren Daten und nach fangen sie

SELECT 
* 
FROM 
(SELECT 
    t.*, @rownum:[email protected] + 1 AS rank 
FROM 
    myTabel t, (SELECT @rownum:=0) r 
ORDER BY ColumnToSort) AS B 
WHERE 
    B.rank = (SELECT 
      ROUND(COUNT(*)/2, 0) 
     FROM 
      myTable) 

Grundsätzlich ausgerichtet Creta, möchten Sie die Zeile mit Zeilennummer gleich der Hälfte der Auswahl bekommen . MySql unterstützt keine Funktion, die diesen Wert zurückgibt, so dass Sie sich selbst erstellen müssen. Eine sehr gute Referenz kann hier (MySQL - Get row number on select)

Der Hauptcode ist hinter dieser wenige Code-Zeile gefunden:

SELECT 
    t.*, @rownum:[email protected] + 1 AS rank 
FROM 
    myTabel t, (SELECT @rownum:=0) r 
ORDER BY ColumnToSort 
1

Leider kann man nicht enthalten Ausdrücke in den limit. Sie könnte zählen Sie die Anzahl der Zeilen in der Tabelle und dann übergeben Sie das als das Limit.

Ich würde normalerweise verwenden:

select avg(n) 
from (select t.*, (@rn := @rn + 1) as rn 
     from (select t.* 
      from t 
      order by n 
      ) t cross join 
      (select @rn := 0) params 
    ) t 
where 2 * rn in (@rn - 1, @rn, @rn + 1); 

Hinweise:

  • Die zusätzliche Ebene von Unterabfragen in den neuesten Versionen von MySQL benötigt - Parameter nicht immer mit order by mischen.
  • Die where funktioniert sowohl für gerade als auch für ungerade Reihen.
  • Die avg() nimmt den Mittelpunkt, wenn die Anzahl der Zeilen gerade ist.