Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

mysql - precisa de dois limites?


Você terá que fazer isso aplicando uma "classificação" por distrito, então apenas pegue por classificação =1... O @LastDistrict no local de junção é zero, caso o distrito seja baseado em um ID. Se o distrito for baseado em char, você pode simplesmente alterá-lo para ="" para corresponder ao tipo de dados.

Para esclarecer o que está acontecendo. A pré-consulta "AwardCounts" faz a consulta inteira por distrito e membro com quantas contagens de prêmios. Em seguida, ordenado por distrito e número de prêmios de sócios (decrescente), colocando assim o maior número de prêmios na primeira posição por distrito.

Isso se junta a outro alias falso "SQLVars", que apenas cria variáveis ​​em linha para a consulta chamada @RankSeq e @LastDistrict. Assim, na primeira vez, o "DistRankSeq" se tornará um 1 para o primeiro distrito, então prime o "@LastDistrict" com o valor do distrito. A próxima entrada para o mesmo distrito (já que estará na ordem de seqüência apropriada) será atribuída a classificação de 2, depois 3, etc... Quando houver uma mudança de qualquer que seja o "ÚLTIMO" Distrito para o novo registro testado, a classificação é redefinida para 1 e começa de novo. Então você pode ter um distrito com 100 membros, outro com 5, outro com 17...

Então, sua consulta final tem todos eles com seus respectivos ranks... Agora, aplique o TER o rank final do distrito =1... Fazendo isso, você também pode ajustar a necessidade de obter os 3 melhores membros por distrito (por exemplo )...
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

EDITAR POR FEEDBACK Se for a agregação que está demorando, então eu faria o seguinte. Crie uma nova tabela com nada além das agregações por distrito, nome e classificação inicial do distrito. À medida que qualquer novo registro é adicionado a essa tabela, o gatilho adiciona um à contagem da tabela agregada, verifica onde essa pessoa está em seu distrito e atualiza novamente sua nova posição de classificação. Você poderia dar um passo adiante e ter outra tabela apenas de membros "TOP" por distrito, que é um por distrito com o nome da pessoa. Quando uma nova pessoa atinge a primeira posição, seu nome é colocado na tabela, substituindo quem esteve lá por último.