Maison  >  Questions et réponses  >  le corps du texte

Récupérez les n premiers enregistrements dans chaque résultat groupé

<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粉785957729P粉785957729447 Il y a quelques jours429

répondre à tous(2)je répondrai

  • P粉340264283

    P粉3402642832023-08-22 19:25:52

    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.

    répondre
    0
  • P粉404539732

    P粉4045397322023-08-22 13:19:02

    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

    répondre
    0
  • Annulerrépondre