sql >> Databáze >  >> RDS >> Mysql

v rámci skupinových řazení v mysql

Chybí funkce okna, můžete si objednat tbl a pomocí uživatelských proměnných si sami vypočítejte pořadí svých oddílů (hodnoty "datum"):

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;

Aktualizovat

Co tedy dělá tento dotaz?

Používáme uživatelské proměnné „procházet“ seřazenou sadu výsledků, zvyšovat nebo vynulovat počítadlo (@rank ) podle toho, který souvislý segment sady výsledků (sledováno v @partition ) jsme tam.

V dotazu A inicializujeme dvě uživatelské proměnné. V dotazu B získáme záznamy vaší tabulky v pořadí, které potřebujeme:nejprve podle data a poté podle hodnoty. A a B společně vytvoří odvozenou tabulku tbl_ordered , vypadá to nějak takto:

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

Pamatujte, že nás ve skutečnosti nezajímají sloupce dummy.rank a dummy.partition — jsou to jen náhody toho, jak inicializujeme proměnné @rank a @partition .

V dotazu C procházíme záznamy odvozené tabulky. To, co děláme, je víceméně to, co dělá následující pseudokód:

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)

Nakonec zadejte dotaz D promítne všechny sloupce z C kromě pro sloupec obsahující @partition (který jsme nazvali dummy a nemusí se zobrazovat).



  1. Zkontrolujte verzi SQLite

  2. Použití automatizace k urychlení testů vydání na Galera Cluster s ClusterControl

  3. MYSQL UPDATE SET ve stejném sloupci, ale s více klauzulemi WHERE

  4. IF... ELSE v klauzuli WHERE MySQL