2012-03-21 52 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

相关问题