522 votes

MySQL : à l’aide de limite au sein de GROUP BY pour obtenir des résultats de N par groupe ?

La requête suivante :

rendements :

Ce que je voudrais est seulement les résultats de top 5 pour chaque id (donc vous obtiendriez 2006, 203, 2001, 2007 pour p01, 2008et, 2001, 2004, 2002, 2003 pour p02). Est-il possible de le faire en utilisant une sorte de limite comme modificateur qui fonctionne w/dans le GROUP BY ?

Merci !

158voto

fthiella Points 21512

Vous pouvez utiliser GROUP_CONCAT agrégées en fonction permettant d'obtenir toutes les années en une seule colonne, regroupés en id et commandé par rate:

SELECT   id, GROUP_CONCAT(year ORDER BY rate DESC) grouped_year
FROM     yourtable
GROUP BY id

Résultat:

-----------------------------------------------------------
|  ID | GROUPED_YEAR                                      |
-----------------------------------------------------------
| p01 | 2006,2003,2008,2001,2007,2009,2002,2004,2005,2000 |
| p02 | 2001,2004,2002,2003,2000,2006,2007                |
-----------------------------------------------------------

Et ensuite, nous pouvons utiliser FIND_IN_SET, qui retourne la position du premier argument insite la seconde, par exemple.

SELECT FIND_IN_SET('2006', '2006,2003,2008,2001,2007,2009,2002,2004,2005,2000');
1

SELECT FIND_IN_SET('2009', '2006,2003,2008,2001,2007,2009,2002,2004,2005,2000');
6

pour limiter le retour des années qui ont FIND_IN_SET(year, grouped_years)<=5.

En utilisant une combinaison de GROUP_CONCAT et FIND_IN_SET vous pouvez ensuite utiliser cette requête qui ne renvoie que les 5 premières années pour chaque id:

SELECT
  yourtable.*
FROM
  yourtable INNER JOIN (
    SELECT
      id,
      GROUP_CONCAT(year ORDER BY rate DESC) grouped_year
    FROM
      yourtable
    GROUP BY id) group_max
  ON yourtable.id = group_max.id
     AND FIND_IN_SET(year, grouped_year) <=5
ORDER BY
  yourtable.id, yourtable.year DESC;

Veuillez voir tripoter ici.

Veuillez noter que si plus d'une ligne peut avoir le même taux, vous devriez envisager d'utiliser GROUP_CONCAT(DISTINCTES des taux PAR taux) sur le taux de colonne à la place de la colonne d'année.

La longueur maximale de la chaîne de caractères retournée par GROUP_CONCAT est limitée, de sorte que cela fonctionne bien si vous avez besoin de sélectionner quelques enregistrements pour chaque groupe.

102voto

danben Points 35312

Cela peut être fait dans MySQL, mais il n’est pas aussi simple que l’ajout d’un `` article. Voici un article qui explique le problème en détail :

Comment sélectionner la ligne première/moins/max par groupe dans SQL

C’est un bon article - il présente un élégant mais naïf la solution au problème « Top N par groupe » et puis s’améliore graduellement à ce sujet.

23voto

Vishal Kumar Points 130

pour moi quelque chose comme SUBSTRING_INDEX (group_concat (nom_colonne ordre de desired_col_order_name), «, », N) fonctionne parfaitement. Aucune requête de complicted.

10voto

Cela exige une série de sous-requêtes pour classer les valeurs, limitez-les, puis effectuer la somme tout groupement

9voto

Saharsh Shah Points 11307

Essayez ceci :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X