Récupérez les n premiers enregistrements dans chaque résultat groupé
P粉785957729
P粉785957729 2023-08-21 19:55:22
0
2
461
<p>Ce qui suit est l'exemple le plus simple possible, mais toute solution doit pouvoir s'adapter aux n meilleurs résultats requis : </p> <p>Étant donné le tableau suivant, qui contient des colonnes pour les personnes, les groupes et les âges, comment obtenez-vous les deux personnes les plus âgées de chaque groupe ? (Les égalités au sein d'un groupe ne devraient pas produire plus de résultats, mais plutôt donner les 2 premiers par ordre alphabétique) </p> <pré> +--------+-------+-----+ | Personne Groupe | Âge | +--------+-------+-----+ | |Jill|1|34| | | Jacques | 2 | 29 | | | +--------+-------+-----+ ≪/pré> <p>Ensemble de résultats souhaité : </p> <pré> +--------+-------+-----+ | |Jill|1|34| | | +--------+-------+-----+ ≪/pré> <hr>

J'ai reçu une bonne réponse spécifique à MySQL de la part de @Bohemian : </p> <pre class="brush:php;toolbar:false;">sélectionner * de (sélectionnez * dans mytable, commandez par « Groupe », âge, personne) x regrouper par `Group`</pre> <p>Ce serait bien de pouvoir s'appuyer sur cela, mais je ne vois pas comment. </p>

P粉785957729
P粉785957729

répondre à tous(2)
P粉340264283

Dans d'autres bases de données, vous pouvez utiliser ROW_NUMBER来实现此功能。MySQL不支持ROW_NUMBER mais vous pouvez le simuler à l'aide de variables :

SELECT
    person,
    groupname,
    age
FROM
(
    SELECT
        person,
        groupname,
        age,
        @rn := IF(@prev = groupname, @rn + 1, 1) AS rn,
        @prev := groupname
    FROM mytable
    JOIN (SELECT @prev := NULL, @rn := 0) AS vars
    ORDER BY groupname, age DESC, person
) AS T1
WHERE rn <= 2

Démo en ligne : sqlfiddle


EDIT Je viens de remarquer que bluefeet a posté une réponse très similaire : +1 pour lui. Mais cette réponse présente deux petits avantages :

  1. Il s’agit d’une seule requête. Les variables sont initialisées dans l'instruction SELECT.
  2. Il gère la situation parallèle décrite dans la question (par ordre alphabétique de nom).

Je le garde donc au cas où cela aiderait quelqu'un.

P粉404539732

Voici une façon d'ajouter une requête en utilisant UNION ALL(请参见带有演示的SQL Fiddle)。这适用于两个组,如果你有多个组,则需要指定group编号并为每个group :

(
  select *
  from mytable 
  where `group` = 1
  order by age desc
  LIMIT 2
)
UNION ALL
(
  select *
  from mytable 
  where `group` = 2
  order by age desc
  LIMIT 2
)

Il existe plusieurs façons d'y parvenir, veuillez vous référer à cet article pour déterminer la meilleure méthode selon votre situation :

http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/

Éditeur :

Cela peut fonctionner pour vous aussi, cela génère un numéro de ligne pour chaque enregistrement. En utilisant l'exemple du lien ci-dessus, il ne renverra que les enregistrements dont les numéros de ligne sont inférieurs ou égaux à 2 :

select person, `group`, age
from 
(
   select person, `group`, age,
      (@num:=if(@group = `group`, @num +1, if(@group := `group`, 1, 1))) row_number 
  from test t
  CROSS JOIN (select @num:=0, @group:=null) c
  order by `Group`, Age desc, person
) as x 
where x.row_number <= 2;

Voir Démo

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal