2012-03-21 3 views
0

J'ai une liste user_id de N entiers, par ex.MySQL: un moyen de transformer ces N requêtes en moins de requêtes?

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

et une table:

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

Je dois prendre ces N entiers de user_id et pour chaque user_id obtenir le top 3 content qui a le plus score. Donc, fondamentalement, je dois exécuter cette requête N fois:

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

N pourrait être un très grand nombre. Donc, je voudrais vraiment éviter d'exécuter ces requêtes une par une.

Y at-il un moyen de réduire le nombre de requêtes que je dois exécuter? Une sorte de masse choisir peut-être?

+0

Regardez à travers la balise 'most-n-per-group' – newtover

+1

oui, par exemple http://stackoverflow.com/questions/5319643/top-n-per-group-with-multiple-table-joins – Daan

+0

autre : http://stackoverflow.com/questions/1442527/how-to-select-the-newest-four-items-per-category/1442867#1442867 – newtover

Répondre

1

Cela devrait fonctionner:

$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 

Peut-être qu'il ya une meilleure façon de le faire. Si une telle; faites le moi savoir!

+0

Il y a certainement des variations plus efficaces, mais l'idée est la même. – newtover

+0

@newtover - quelle serait une variation plus efficace? – Continuation

+0

@continuation, le plus efficace est de parcourir l'index pendant un scan d'index et d'obtenir les identifiants requis, puis de rejoindre le reste des champs. La solution donnée crée deux fois une copie complète de la table, puis applique une condition dans une analyse complète. De plus, il ne peut utiliser complètement aucun index à cause de ASC et DESC en même temps. – newtover