Pergunta

Eu tenho uma tabela simples de dados e gostaria de selecionar a linha com cerca de 40º percentil da consulta.

Eu posso fazer isso agora, consultando primeiro para encontrar o número de linhas e depois executar outra consulta que classifica e seleciona a enésima linha:

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

que pode retornar algo como 93, 93*0,4 = 37

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

Posso combinar essas duas consultas em uma única consulta?

Foi útil?

Solução

Isso fornecerá aproximadamente o 40º percentil, retorna a linha, onde 40% das linhas são menores que isso. Ele classifica as linhas por quão longe elas estão do 40º percentil, pois nenhuma linha pode cair exatamente no percentil 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

Outras dicas

Como um exercício de futilidade (sua solição atual provavelmente seria mais rápida e preferida), se a tabela for Myisam (ou você pode viver com a aproximação do 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';

Há também isto Solução, que usa uma string monstro fabricada por group_concat. Eu tive que aumentar o máximo na saída, como fazê -lo funcionar:

SET SESSION group_concat_max_len = 1000000;

MySQL Wizards por aí: fique à vontade para comentar o desempenho relativo dos métodos.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top