MySQL:如何按记录数量的百分比进行LIMIT限制?

12

假设我有一个值的列表,就像这样:

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

但这并不起作用。问题在于在执行查询之前我不知道记录的数量。有任何想法吗?


1
可能是Mysql set LIMIT to string的重复问题。 - OMG Ponies
1
可能是重复的问题:将SQL Server查询转换为MySQL - Anax
2
最佳答案来自重复问题:http://stackoverflow.com/questions/5522433/convert-sql-server-query-to-mysql/5522462#5522462 - Lightness Races in Orbit
5个回答

17

我找到的最佳答案:

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更改为其他数字以获取不同的百分比。


5

如果你是在处理乱序或随机情况,我开始采用以下样式:

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

如果你需要随机但可控的结果,你可以使用一个种子值(以下是使用PHP的示例代码):

如果您需要将其随机但仍可控制,可以使用一个种子值(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)


4
请注意,这些查询可能返回从零条记录到全部记录的任意结果(只是每条记录被包含在结果集中的概率为0.1)。 - eggyal

3
你可以尝试以下方法:
SET @amount =(SELECT COUNT(*) FROM page) /10;
PREPARE STMT FROM 'SELECT * FROM page LIMIT ?';
EXECUTE STMT USING @amount;

这是MySQL的一个bug,详细描述在这里:http://bugs.mysql.com/bug.php?id=19795。希望对您有所帮助。

0

我知道这篇文章很古老,但是当你在谷歌搜索"SQL按百分比限制"的时候,它仍然会显示在顶部结果中,所以我想让你节省些时间。现如今,这很容易实现。以下内容可以帮助作者获取他们所需的结果:

    SELECT TOP 10 PERCENT
    id, 
    value 
    FROM list
    ORDER BY value DESC

要快速而粗略地获取表格的随机10%,可以使用以下代码:
    SELECT TOP 10 PERCENT
    id, 
    value 
    FROM list
    ORDER BY NEWID()

-1
我有一个替代方案,其他答案中没有提到:如果您从具有完全访问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(),因为后者要求您始终接受所有所需的行。

另一方面,我的解决方案的流量可能太高了 - 所有行都必须传输。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接