假设我有一个值列表,如下所示:
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
但这不起作用。问题是我在查询之前不知道记录的数量。有什么想法吗?
答案 0 :(得分:13)
我找到的最佳答案:
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以获得不同的百分比。
答案 1 :(得分:4)
如果您因为乱序或随机情况而这样做 - 我已经开始使用以下样式:
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 :(得分:2)
你也可以尝试:
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
希望它会有所帮助。
答案 3 :(得分:-1)
我有一个替代方案,在其他答案中没有提到:如果您从任何语言访问您可以完全访问MySQL API(即不是MySQL CLI),您可以启动查询,询问有多少如果是时间的话会有行然后打破循环。
E.g。在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,我的解决方案的流量可能太高 - 所有行都必须转移。