2011-04-10 31 views
6

Digamos que tengo una lista de valores, así:MySQL: ¿LÍMITE por un porcentaje de la cantidad de registros?

id value 
---------- 
A 53 
B 23 
C 12 
D 72 
E 21 
F 16 
.. 

necesito la parte superior 10 ciento de esta lista - Traté:

SELECT id, value 
    FROM list 
ORDER BY value DESC 
    LIMIT COUNT(*)/10 

Pero esto no lo hace trabajo. El problema es que no sé la cantidad de registros antes de hacer la consulta. ¿Algunas ideas?

+1

posible duplicado de [Mysql Establecer límite a string] (http://stackoverflow.com/questions/1309137/mysql-set-limit-to-string) –

+1

posible duplicado de [Convertir consulta SQL Server a MySQL] (http://stackoverflow.com/questions/5522433/convert-sql-server-query-to- mysql) – Anax

+2

La mejor respuesta de los dups: http://stackoverflow.com/questions/5522433/convert-sql-server-query-to-mysql/5522462#5522462 –

Respuesta

10

mejor respuesta que encontró:

SELECT* 
FROM (
    SELECT list.*, @counter := @counter +1 AS counter 
    FROM (select @counter:=0) AS initvar, list 
    ORDER BY value DESC 
) AS X 
where counter <= (10/100 * @counter); 
ORDER BY value DESC 

Cambiar la 10 para obtener un porcentaje diferente.

2

También puede probar con eso:

SET @amount =(SELECT COUNT(*) FROM page) /10; 
PREPARE STMT FROM 'SELECT * FROM page LIMIT ?'; 
EXECUTE STMT USING @amount; 

Esto es error MySQL se describe aquí: http://bugs.mysql.com/bug.php?id=19795

Espero que va a ayudar.

0

Tengo una alternativa que no se ha mencionado en las otras respuestas: si accede desde cualquier idioma donde tenga acceso completo a la API de MySQL (es decir, no la CLI de MySQL), puede iniciar la consulta, pregunte cómo muchas filas habrá y luego romper el ciclo si es el momento.

E.g. en Python:

... 
maxnum = cursor.execute(query) 
for num, row in enumerate(query) 
    if num > .1 * maxnum: # Here I break the loop if I got 10% of the rows. 
     break 
    do_stuff... 

Esto sólo funciona con mysql_store_result(), no con mysql_use_result(), ya que éste requiere que siempre acepta todas las filas necesarias.

OTOH, el tráfico de mi solución podría ser demasiado alto: todas las filas deben transferirse.

4

En caso de que usted está haciendo esto por un fuera de orden, o una situación aleatoria - He empezado a utilizar el siguiente estilo:

SELECT id, value FROM list HAVING RAND() > 0.9 

Si lo necesita ser al azar, pero controlable se puede utilizar una semilla (ejemplo con PHP):

SELECT id, value FROM list HAVING RAND($seed) > 0.9 

Por último - si se trata de una especie de cosa que tiene un control total sobre realidad se puede agregar una columna que contiene un valor aleatorio cada vez que se inserta una fila, y luego consulta usando ese

SELECT id, value FROM list HAVING `rand_column` BETWEEN 0.8 AND 0.9 

Dado que este no requiere clasificación, o ORDER BY - es O (n) en lugar de O (n lg n)

+4

Tenga en cuenta que estas consultas pueden devolver cualquier cosa desde ningún registro a todas ellas (simplemente se trata de que la probabilidad de que un registro determinado esté en el conjunto de resultados es 0.1). – eggyal

Cuestiones relacionadas