sql >> Base de Datos >  >> RDS >> Mysql

mysql:¿necesita dos límites?

Tendrá que hacerlo aplicando un "rango" por distrito, luego solo tome por rango =1... El @LastDistrict en la ubicación de unión está predeterminado en cero, en caso de que el distrito se base en una ID. Si el distrito está basado en caracteres, puede cambiarlo a ="" en su lugar para que coincida con el tipo de datos.

Para aclarar lo que está pasando. La consulta previa "AwardCounts" realiza la consulta completa por distrito y miembro con el número de premios que sea. Luego, ordenado por distrito y recuento de premios de miembros (descendente), colocando así el recuento de premios más alto en la primera posición por distrito.

Eso se une a otro alias falso "SQLVars" que solo crea variables en línea para la consulta llamada @RankSeq y @LastDistrict. Entonces, la primera vez que ingrese, "DistRankSeq" se convertirá en 1 para el primer distrito, luego primará "@LastDistrict" con el valor del distrito. A la siguiente entrada para el mismo distrito (dado que estará en el orden de secuencia correcto) se le asignará el rango de 2, luego 3, etc. Cuando haya un cambio de lo que fuera el "ÚLTIMO" Distrito al nuevo registro que se está probado, el rango se vuelve a establecer en 1 y comienza de nuevo. Entonces podrías tener un distrito con 100 miembros, otro con 5, otro con 17...

Entonces, su consulta final los tiene a todos con sus respectivos rangos... Ahora, aplique el TENIENDO el rango final del distrito =1... Al hacer esto, también podría ajustar el tener que obtener los 3 mejores miembros por distrito (por ejemplo )...

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 COMENTARIOS Si es la agregación la que se está tomando el tiempo, entonces haría lo siguiente. Cree una nueva tabla con nada más que las agregaciones por distrito, nombre y rango inicial para el distrito. A medida que se agrega un nuevo registro a esta tabla, el disparador luego agrega uno al conteo agregado de la tabla, luego verifica dónde se encuentra esa persona dentro de su distrito y vuelve a actualizar su nueva posición en la clasificación. Podría dar un paso más y tener otra tabla de solo miembros "TOP" por tabla de distrito que sea una por distrito con el nombre de la persona. Cuando una nueva persona llega a la primera posición, su nombre se coloca en la tabla, sobrescribiendo al último que estuvo allí.