2012-03-21 54 views
0

我有一個列表user_id的整數,例如NMySQL:以任何方式將這些N個查詢變成更少的查詢?

[1001, 1023, 13452, 1679834, ...] 

和表:

CREATE TABLE content (
    id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    user_id INT, 
    content VARCHAR(100), 
    score INT 
); 

我需要那些N整數從user_id和每個user_id獲得前3 content具有最高score。所以基本上我需要運行此查詢N時間:

SELECT * 
FROM content 
WHERE user_id=1001 
ORDER BY score DESC 
LIMIT 3; 

N可能是一個非常大的數字。所以我非常想避免一個一個地運行這些查詢。

有什麼辦法可以減少我需要運行的查詢次數嗎?某種批量選擇也許?

+0

通過「每個組最大的標籤」標籤 – newtover 2012-03-21 21:52:21

+1

是的,例如http://stackoverflow.com/questions/5319643/top-n-per-group-with-multiple-table-joins – Daan 2012-03-21 21:56:08

+0

另一個:http://stackoverflow.com/questions/1442527/how-to-select-the-newest-four-items-per-category/1442867#1442867 – newtover 2012-03-21 22:25:28

回答

1

這應該工作:

$str_ids = implode(', ', $arr_ids);

SELECT id, user_id, content, score 
FROM ( SELECT *, (@rownum := @rownum + 1) AS rownum, 
      case when @user_id IS NULL then @user_id := c.user_id when @user_id != c.user_id then CONCAT(@rownum := 0, @user_id := c.user_id) AS dummy_value 
     FROM ( SELECT * 
       FROM content 
       WHERE user_id IN ({$str_ids}) 
       ORDER BY user_id ASC, score DESC) AS c, (@rownum := 1, @user_id := NULL) AS vars 
     HAVING rownum <= 3 

也許有一個更好的方式來做到這一點。如果這樣;讓我知道!

+0

肯定有更有效的變化,但想法是一樣的。 – newtover 2012-03-21 22:18:27

+0

@newtover - 更有效的變化是什麼? – Continuation 2012-03-21 22:26:13

+0

@continuation,最有效的方法是在索引掃描期間遍歷索引並獲取所需的id,然後加入其餘字段。給定的解決方案會創建兩次表格的完整副本,然後在全面掃描中應用條件。另外,由於ASC和DESC同時不能完全使用任何索引。 – newtover 2012-03-21 22:40:36

相關問題