Mysql
 sql >> Base de données >  >> RDS >> Mysql

mysql - besoin de deux limites ?

Vous devrez le faire en appliquant un "rang" par district, puis seulement saisir par rang =1... Le @LastDistrict à l'emplacement de la jointure est par défaut à zéro, au cas où le district est basé sur un ID. Si district est basé sur des caractères, vous pouvez simplement le changer en ="" à la place pour correspondre au type de données.

Pour clarifier ce qui se passe. La pré-requête "AwardCounts" effectue l'intégralité de la requête par district et membre avec le nombre de récompenses. Ensuite, classés par district et nombre de récompenses des membres (décroissant), plaçant ainsi le nombre de récompenses le plus élevé à la première position par district.

Cela est joint à un autre faux alias "SQLVars" qui crée simplement des variables en ligne pour la requête appelée @RankSeq et @LastDistrict. Ainsi, la première fois, le "DistRankSeq" deviendra un 1 pour le premier district, puis amorcera le "@LastDistrict" avec la valeur du district. La prochaine entrée pour le même district (puisqu'elle sera dans l'ordre de séquence approprié) se verra attribuer le rang 2, puis 3, etc. Lorsqu'il y a un changement de ce que le "DERNIER" District était au nouveau record étant testé, le rang revient à 1 et recommence. Vous pourriez donc avoir un district avec 100 membres, un autre avec 5, un autre avec 17...

Donc, votre requête finale les a tous avec leurs rangs respectifs... Maintenant, appliquez le AYANT le rang final du district =1... Ce faisant, vous pouvez également ajuster le fait d'avoir à obtenir les 3 meilleurs membres par district (par exemple )...

select
      AwardCounts.District,
      AwardCounts.MemberName,
      AwardCounts.memberAwards,
      @RankSeq := if( @LastDistrict = AwardCounts.District, @RankSeq +1, 1 ) DistRankSeq,
      @LastDistrict := AwardCounts.District as ignoreIt
   from
      ( select 
              a.district,
              a.membername,
              count(*) as memberAwards
           from
              Awards a
           group by
              a.district,
              a.membername
           order by
              a.district,
              memberAwards desc ) AwardCounts

      JOIN (select @RankSeq := 0, @LastDistrict = 0 ) SQLVars
   HAVING
      DistRankSeq = 1

MODIFIER PAR COMMENTAIRES Si c'est l'agrégation qui prend du temps, alors je ferais ce qui suit. Créez un nouveau tableau avec rien d'autre que les agrégations par district, le nom et le rang initial du district. Au fur et à mesure qu'un nouvel enregistrement est ajouté à ce tableau, le déclencheur en ajoute un au nombre total de tableaux, puis vérifie où se trouve cette personne dans son district et met à jour sa nouvelle position de classement. Vous pouvez aller plus loin et avoir une autre table de membres "TOP" par district, c'est-à-dire un par district avec le nom de la personne. Lorsqu'une nouvelle personne atteint la première position, son nom est mis dans le tableau, écrasant celui qui était là en dernier.