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

dentro de classificações de grupo no mysql


Funções de janela ausentes, você pode solicitar tbl e use variáveis ​​de usuário para calcular a classificação sobre suas partições (valores de "data"):
SELECT "date",                                                -- D) Desired columns
       id,
       value,
       rank
  FROM (SELECT "date",                                        -- C) Rank by date
               id,
               value,
               CASE COALESCE(@partition, "date")
                 WHEN "date" THEN @rank := @rank + 1
                 ELSE             @rank := 1
               END AS rank,
               @partition := "date" AS dummy
          FROM (SELECT @rank := 0 AS rank,                    -- A) User var init
                       @partition := NULL AS partition) dummy
               STRAIGHT_JOIN
               (  SELECT "date",                              -- B) Ordering query
                         id,
                         value
                    FROM tbl
                ORDER BY date, value) tbl_ordered;

Atualizar


Então, o que essa consulta está fazendo?

Estamos usando variáveis ​​de usuário para "loop" através de um conjunto de resultados ordenado, incrementando ou redefinindo um contador (@rank ) dependendo de qual segmento contíguo do conjunto de resultados (rastreado em @partition ) estavam em.

Na consulta A inicializamos duas variáveis ​​de usuário. Na consulta B obtemos os registros de sua tabela na ordem que precisamos:primeiro por data e depois por valor. A e B juntos fazem uma tabela derivada, tbl_ordered , que se parece com isso:
rank | partition | "date" |  id  | value 
---- + --------- + ------ + ---- + -----
  0  |   NULL    |   d1   |  id2 |    1
  0  |   NULL    |   d1   |  id1 |    2
  0  |   NULL    |   d2   |  id1 |   10
  0  |   NULL    |   d2   |  id2 |   11

Lembre-se, nós realmente não nos importamos com as colunas dummy.rank e dummy.partition — são apenas acidentes de como inicializamos as variáveis ​​@rank e @partition .

Na consulta C fazemos um loop pelos registros da tabela derivada. O que estamos fazendo é mais ou menos o que o seguinte pseudocódigo faz:
rank      = 0
partition = nil

foreach row in fetch_rows(sorted_query):
  (date, id, value) = row

  if partition is nil or partition == date:
    rank += 1
  else:
    rank = 1

  partition = date

  stdout.write(date, id, value, rank, partition)

Por fim, consulte D projeta todas as colunas de C exceto para a coluna que contém @partition (que chamamos de dummy e não precisa exibir).