2011-12-26 15 views
6
[tbl_votes] 
- id <!-- unique id of the vote) --> 
- item_id <!-- vote belongs to item <id> --> 
- vote <!-- number 1-10 --> 

Por supuesto que podemos arreglar esto consiguiendo:¿Cómo puedo devolver los datos numéricos de cuadro de todos los resultados usando 1 consulta mySQL?

  • la smallest observation (tan)
  • la lower quartile (LQ)
  • la median (me)
  • la upper quartile (UQ)
  • y largest observation (lo)

... uno por uno usando múltiples consultas, pero me pregunto si se puede hacer con una sola consulta.

En Oracle puedo usar COUNT OVER y RATIO_TO_REPORT, pero esto no es compatible con mySQL.

Para aquellos que no saben lo que es un diagrama de caja es: http://en.wikipedia.org/wiki/Box_plot

se agradecería cualquier ayuda.

+0

Ver http: // stackoverflow.com/questions/1057027/calculating-percentile-rank-in-mysql –

+0

Esa es una solución muy sucia si me preguntas ... –

Respuesta

0

Aquí es un ejemplo de cálculo de los cuartiles para e256 rangos de los valores dentro de e32 grupos, un índice en (E32, E256) en este caso es una obligación:

SELECT 
    @group:=IF([email protected], e32, GREATEST(@index:=-1, e32)) as e32_, 
    MIN(e256) as so, 
    MAX(IF(lq_i=(@index:[email protected]+1), e256, NULL)) as lq, 
    MAX(IF([email protected], e256, NULL)) as me, 
    MAX(IF([email protected], e256, NULL)) as uq, 
    MAX(e256) as lo 
FROM (SELECT @index:=NULL, @group:=NULL) as init, test t 
JOIN (
    SELECT e32, 
    COUNT(*) as cnt, 
    (COUNT(*) div 4) as lq_i, -- lq value index within the group 
    (COUNT(*) div 2) as me_i, -- me value index within the group 
    (COUNT(*) * 3 div 4) as uq_i -- uq value index within the group 
    FROM test 
    GROUP BY e32 
) as cnts 
USING (e32) 
GROUP BY e32; 

Si no hay necesidad en agrupaciones , la consulta será un poco más simple.

P.S. test es mi mesa de juegos de valores aleatorios donde e32 es el resultado de Python int(random.expovariate(1.0) * 32), etc.

2

He encontrado una solución en PostgreSQL usando PL/Python.

Sin embargo, dejo la pregunta abierta en caso de que alguien más encuentre una solución en mySQL.

CREATE TYPE boxplot_values AS (
    min  numeric, 
    q1  numeric, 
    median numeric, 
    q3  numeric, 
    max  numeric 
); 

CREATE OR REPLACE FUNCTION _final_boxplot(strarr numeric[]) 
    RETURNS boxplot_values AS 
$$ 
    x = strarr.replace("{","[").replace("}","]") 
    a = eval(str(x)) 

    a.sort() 
    i = len(a) 
    return (a[0], a[i/4], a[i/2], a[i*3/4], a[-1]) 
$$ 
LANGUAGE 'plpythonu' IMMUTABLE; 

CREATE AGGREGATE boxplot(numeric) (
    SFUNC=array_append, 
    STYPE=numeric[], 
    FINALFUNC=_final_boxplot, 
    INITCOND='{}' 
); 

Ejemplo:

SELECT customer_id as cid, (boxplot(price)).* 
FROM orders 
GROUP BY customer_id; 

    cid | min | q1 | median | q3 | max 
-------+---------+---------+---------+---------+--------- 
    1001 | 7.40209 | 7.80031 | 7.9551 | 7.99059 | 7.99903 
    1002 | 3.44229 | 4.38172 | 4.72498 | 5.25214 | 5.98736 

Fuente: http://www.christian-rossow.de/articles/PostgreSQL_boxplot_median_quartiles_aggregate_function.php

0

Bueno, yo puedo hacerlo en dos consultas. Haz la primera consulta para obtener las posiciones de los cuartiles y luego usa la función de límite para obtener las respuestas en la segunda consulta.

mysql> seleccionar (seleccionar piso (count (*)/4)) como first_q, (seleccionar piso (count (*)/2) de customer_data) como mid_pos, (seleccionar piso (count (*)/4 * 3) from customer_data) como third_q from customer_data order por measure limit 1;

mysql> seleccione min (medida), (seleccione medida de customer_data ordene por límite de medida 0,1) como firstq, (seleccione measure from customer_data order por measure limit 5,1) como mediana, (seleccione measure from customer_data order por límite de medida 8,1) como last_q, max (measure) from customer_data;

+0

¿Cómo estás utilizando tus primeras posiciones de consulta en tu segunda consulta? – Naveen

Cuestiones relacionadas