Selezionare percentile ennesima da MySQL
-
28-09-2019 - |
Domanda
Ho una semplice tabella di dati, e mi piacerebbe per selezionare la riga di quella a circa il 40 ° percentile dalla query.
posso farlo adesso da prima interrogazione per trovare il numero di righe e quindi eseguire un'altra query che ordina e seleziona l'ennesima riga:
select count(*) as `total` from mydata;
che può restituire qualcosa come 93, 93 * 0.4 = 37
select * from mydata order by `field` asc limit 37,1;
Posso combinare questi due query in una singola query?
Soluzione
Questo vi darà circa 40 ° percentile, restituisce la riga in cui il 40% di righe sono meno di esso. Si ordina righe per quanto lontano sono da percentile 40 °, dal momento che nessuna riga può cadere esattamente sul 40 ° percentile.
SELECT m1.field, m1.otherfield, count(m2.field)
FROM mydata m1 INNER JOIN mydata m2 ON m2.field<m1.field
GROUP BY
m1.field,m1.otherfield
ORDER BY
ABS(0.4-(count(m2.field)/(select count(*) from mydata)))
LIMIT 1
Altri suggerimenti
Come un esercizio di futilità (vostra attuale soluzione sarebbe probabilmente più veloce e preferivamo), se la tabella è MyISAM (o si può vivere con il ravvicinamento delle InnoDB):
SET @row =0;
SELECT x.*
FROM information_schema.tables
JOIN (
SELECT @row := @row+1 as 'row',mydata.*
FROM mydata
ORDER BY field ASC
) x
ON x.row = round(information_schema.tables.table_rows * 0.4)
WHERE information_schema.tables.table_schema = database()
AND information_schema.tables.table_name = 'mydata';
C'è anche questa soluzione , che utilizza una stringa mostro fatto da group_concat. Ho dovuto il massimo in uscita in questo modo per farlo funzionare:
SET SESSION group_concat_max_len = 1000000;
MySql maghi là fuori:. Sentitevi liberi di commentare sulla performance relativa dei metodi