Mysql
 sql >> Database >  >> RDS >> Mysql

mysql:servono due limiti?

Dovrai farlo applicando un "rank" per distretto, quindi solo grab per rank =1... Il @LastDistrict nella posizione di unione è impostato su zero, nel caso in cui il distretto sia basato su un ID. Se il distretto è basato sui caratteri, puoi semplicemente cambiarlo in ="" invece in modo che corrisponda al tipo di dati.

Per chiarire cosa sta succedendo. La pre query "AwardCounts" esegue l'intera query per distretto e membro con il numero di conteggi dei premi. Quindi, ordinato per distretto e conteggio dei premi dei membri (decrescente), mettendo così il conteggio dei premi più alto al primo posto per distretto.

Questo è unito a un altro falso alias "SQLVars" che crea semplicemente variabili inline nella query chiamata @RankSeq e @LastDistrict. Quindi, la prima volta in, "DistRankSeq" diventerà un 1 per il primo distretto, quindi adescherà "@LastDistrict" con il valore del distretto. Alla voce successiva per lo stesso distretto (poiché sarà nell'ordine di sequenza corretto) verrà assegnato il rango 2, poi 3, ecc... Quando c'è un cambiamento da qualunque fosse il Distretto "ULTIMO" al nuovo record essendo testato, il grado viene riportato a 1 e ricomincia da capo. Quindi potresti avere un distretto con 100 membri, un altro con 5, un altro con 17...

Quindi, la tua query finale li ha tutti con i loro rispettivi ranghi... Ora, applica AVENDO il rango finale del distretto =1... In questo modo, potresti anche regolare la necessità di ottenere i primi 3 membri per distretto (ad esempio )...

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

MODIFICA PER FEEDBACK Se è l'aggregazione che richiede tempo, allora farei quanto segue. Crea una nuova tabella con nient'altro che le aggregazioni per distretto, nome e rango iniziale per il distretto. Man mano che un nuovo record viene aggiunto a questa tabella, il trigger ne aggiunge uno al conteggio aggregato della tabella, quindi controlla dove si trova quella persona all'interno del proprio distretto e aggiorna nuovamente la sua nuova posizione di rango. Potresti fare un ulteriore passo avanti e avere un altro tavolo di membri "TOP" per distretto, uno per distretto con il nome della persona. Quando una nuova persona raggiunge la prima posizione, il suo nome viene inserito nella tabella, sovrascrivendo chi c'era per ultimo.