2011-04-10 277 views
6

比方說,我有值的列表,像這樣:MySQL:LIMIT按記錄數量的百分比?

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的限量字符串]可能重複(http://stackoverflow.com/questions/1309137/mysql-set-limit-to-string) – 2011-04-10 22:38:38

+1

[將SQL Server查詢轉換爲MySQL]可能重複(http://stackoverflow.com/questions/5522433/convert-sql-server-query-to- mysql) – Anax 2011-04-10 22:39:29

+2

來自dups的最佳答案:http://stackoverflow.com/questions/5522433/convert-sql-server-query-to-mysql/5522462#5522462 – 2011-04-10 22:50:58

回答

10

最佳答案我發現:

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獲得不同的百分比。

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

希望能對大家有所幫助。

0

我有其他答案中沒有提及的替代方案:如果您從任何語言訪問您有權訪問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,我的解決方案的流量可能太高 - 所有行都必須傳輸。

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)

+4

請注意,這些查詢可能會返回任何從無記錄到全部的記錄(這僅僅是結果集中的任何給定記錄的概率是0.1)。 – eggyal 2014-03-07 08:50:34