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

Nápověda MySQL:Optimalizujte aktualizační dotaz, který nastavuje pořadí podle pořadí jiného sloupce

Nejprve bych změnil budget , cost a rank_score na celé číslo nebo jiný číselný datový typ a místo

UPDATE table_name
SET rank_score = CONCAT(cost, budget) ;

Pak byste použili:

UPDATE table_name
SET rank_score = cost * 1000 + budget * 1  ;

Je to pak jednodušší, protože se nebudete muset zabývat řetězcovými funkcemi a mít něco jako:

SELECT * 
FROM table_name
WHERE (conditions...)
ORDER BY rank_score DESC

(Závorka:má jeden parametr (1000 ) nastavena tak vyšší než druhá (1 ) odpovídá objednávce cost, budget . Zkuste toto zkontrolovat:

SELECT * 
FROM table_name
ORDER BY cost DESC
       , budget DESC

Takže rank_score můžete klidně vypustit celkem, pokud samozřejmě neplánujete experimentovat s různými hodnotami parametrů.

Jak uvedli jiní, není osvědčeným postupem mít pole, které neukládá data, ale výpočet. Je to dennormalizace. Instaed udržujete tabulku normalizovanou a necháte databázi provádět výpočty pokaždé, když to potřebujete:

SELECT id, budget, cost, 
       cost*1000 + budget*1 AS rank_score_calculated
FROM table_name
ORDER BY rank_score_calculated DESC

rank_score_calculated není ve výše uvedeném příkladu uložen. Tímto způsobem nebudete muset aktualizovat počítané pole pokaždé, když se změní rozpočet nebo náklady nebo se do tabulky přidá nový řádek.

Má to jen jednu nevýhodu. Pokud je tabulka opravdu velká a potřebujete, aby tento dotaz (a výpočet) provádělo mnoho uživatelů a velmi často a tabulka je aktualizována poměrně často, může to zpomalit vaši databázi. V takovém případě by se mělo začít přemýšlet o přidání takového pole.

Druhý případ je, když člověk potřebuje absolutní rank ve všech řádcích tabulky, jak potřebujete. Protože MySQL nemá žádné "okenní" funkce, je velmi těžké napsat takový dotaz v čistém SQL.)

Pořadí lze vypočítat pomocí proměnných MySQL

SELECT *
     , @rownum:[email protected]+1 AS rank_calculated
FROM table_name
   , (SELECT @rownum:=0) AS st
ORDER BY rank_score DESC

A pokud chcete tyto hodnoty vložit do rank , použijte:

UPDATE table_name
         JOIN
         ( SELECT id
                , @rownum:[email protected]+1 AS rank_calculated
           FROM table_name
              , (SELECT @rownum:=0) AS st
           ORDER BY rank_score DESC
         ) AS r
         ON r.id = table_name.id
SET table_name.rank = r.rank_calculated ;

Výše uvedené dva dotazy nejsou čisté SQL. Můžete prozkoumat možnost přechodu na jiný daabase systém, který podporuje funkce oken, jako je Postgres, SQL-Server nebo Oracle.



  1. Oracle PL/SQL – kolekce (vnořené tabulky)

  2. Můžeme komunikovat se skriptem psql?

  3. Oracle After Delete Trigger... Jak se vyhnout Mutující tabulce (ORA-04091)?

  4. Jak vypočítat procento růstu týden po týdnu v MySQL