MySQL: LIMIT в процентах от количества записей? - PullRequest
7 голосов
/ 11 апреля 2011

Допустим, у меня есть список значений, например:

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

Мне нужны 10 процентов этого списка - я пробовал:

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

Но это не работает. Проблема в том, что я не знаю количество записей, прежде чем я сделаю запрос. Есть идеи?

Ответы [ 4 ]

13 голосов
/ 19 апреля 2011

Лучший ответ, который я нашел:

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

Измените 10, чтобы получить другой процент.

4 голосов
/ 08 июля 2012

Если вы делаете это из-за неупорядоченности или случайной ситуации - я начал использовать следующий стиль:

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

Если вам нужно, чтобы оно было случайным, но управляемым, вы можете использовать начальное число (пример с PHP):

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

И наконец - если вам требуется полный контроль над этим типом вещи, вы можете добавить столбец, который содержит случайное значение при вставке строки, а затем выполнить запрос, используя

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

Так как для этого не требуется сортировка или ORDER BY - это O (n), а не O (n lg n)

2 голосов
/ 11 апреля 2011

Вы также можете попробовать это:

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

Это ошибка MySQL, описанная здесь: http://bugs.mysql.com/bug.php?id=19795

Надеюсь, это поможет.

0 голосов
/ 17 августа 2011

У меня есть альтернатива, которая не была упомянута в других ответах: если вы обращаетесь к любому языку, у которого есть полный доступ к MySQL API (т.е. не к MySQL CLI), вы можете запустить запрос, спросить, сколькострок будет, а затем прервет цикл, если это время.

Например, в 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...

Это работает только с mysql_store_result(), а не с mysql_use_result(), как последнеетребует, чтобы вы всегда принимали все необходимые строки.

OTOH, трафик для моего решения может быть слишком высоким - все строки должны быть переданы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...