sql >> Databasteknik >  >> RDS >> Mysql

mysql - behöver två gränser?

Du måste göra det genom att tillämpa en "rank" per distrikt, sedan bara ta tag per rank =1... @LastDistrict på anslutningsplatsen är som standard noll, om distriktet är baserat på ett ID. Om distriktet är char-baserat kan du bara ändra det till ="" istället för att matcha datatypen.

För att klargöra vad som händer. Förfrågan "AwardCounts" gör hela frågan per distrikt och medlem med hur många priser som helst. Sedan, sorterat efter antal utmärkelser för distrikt och medlemmar (fallande), vilket ger det högsta antalet utmärkelser vid den första positionen per distrikt.

Det är kopplat till ett annat falskt alias "SQLVars" som bara skapar inline-variabler till frågan som heter @RankSeq och @LastDistrict. Så, första gången i, kommer "DistRankSeq" att bli en 1 för det första distriktet, sedan primer "@LastDistrict" med värdet av distriktet. Nästa post för samma distrikt (eftersom det kommer att vara i rätt ordningsföljd) kommer att tilldelas rangen 2, sedan 3, etc... När det sker en förändring från det "SISTA" distriktet var till det nya rekordet testas, ställs rangordningen tillbaka till 1 och börjar om igen. Så du kan ha ett distrikt med 100 medlemmar, ett annat med 5, ett annat med 17...

Så, din slutliga fråga har alla med sina respektive rangordningar... Nu, använd HA den sista distriktsrankningen =1... Genom att göra detta kan du också justera behovet av att få de tre bästa medlemmarna per distrikt (till exempel )...

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

REDIGERA PER FEEDBACK Om det är aggregeringen som tar tid, då skulle jag göra följande. Skapa en ny tabell med inget annat än sammanställningarna per distrikt, namn och initial rang för distriktet. När varje ny post läggs till i den här tabellen lägger utlösaren sedan till en till det sammanlagda tabellantalet, kontrollerar sedan var personen befinner sig i sitt distrikt och uppdaterar sin nya rangposition på nytt. Du kan ta det ett steg längre och ha en annan tabell med bara "TOP"-medlem per distriktstabell som är en per distrikt med personens namn. När en ny person når toppositionen läggs deras namn i tabellen, vilket skriver över den som var där senast.



  1. Hur man returnerar frågeresultat som en kommaseparerad lista i SQL Server – STRING_AGG()

  2. Extra fält med SQL MIN() &GROUP BY

  3. Att utelämna millisekunderna i ett datum

  4. SQL Server beroenden