Выберите n-й процентиль из MySQL - PullRequest
4 голосов
/ 18 июня 2010

У меня есть простая таблица данных, и я хотел бы выбрать строку, которая находится примерно на 40-м процентиле в запросе.

Я могу сделать это прямо сейчас, сначала запросив числострок, а затем выполняется другой запрос, который сортирует и выбирает n-ую строку:

select count(*) as `total` from mydata;

, которая может возвращать что-то вроде 93, 93 * 0,4 = 37

select * from mydata order by `field` asc limit 37,1;

Могу ли я объединить эти два запросав один запрос?

Ответы [ 3 ]

1 голос
/ 18 июня 2010

Это даст вам приблизительно 40-й процентиль, оно возвращает строку, где 40% строк меньше, чем она.Он сортирует строки по тому, как далеко они находятся от 40-го процентиля, поскольку ни одна строка не может попасть точно на 40-й процентиль.

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
0 голосов
/ 18 марта 2011

Существует также это решение, которое использует строку монстра, созданную GROUP_CONCAT. Мне пришлось увеличить максимум на выходе, чтобы заставить его работать:

SET SESSION group_concat_max_len = 1000000;

Мастера MySql: не стесняйтесь комментировать относительную эффективность методов.

0 голосов
/ 18 июня 2010

В качестве упражнения на бесполезность (ваше текущее решение, вероятно, будет более быстрым и предпочтительным), если таблица MYISAM (или вы можете жить с приближением 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';
...