Ten eerste zou ik budget
veranderen , cost
en rank_score
in integer of ander numeriek datatype en in plaats van
UPDATE table_name
SET rank_score = CONCAT(cost, budget) ;
Dan zou je gebruiken:
UPDATE table_name
SET rank_score = cost * 1000 + budget * 1 ;
Het is dan gemakkelijker omdat je niet met stringfuncties te maken hebt en iets hebt als:
SELECT *
FROM table_name
WHERE (conditions...)
ORDER BY rank_score DESC
(Haakjes:één parameter hebben (1000
) zo hoger ingesteld dan de andere (1
) is gelijk aan het hebben van een bestelling van cost, budget
. Probeer dit om te controleren:
SELECT *
FROM table_name
ORDER BY cost DESC
, budget DESC
Je kunt dus heel goed de rank_score
. laten vallen alles bij elkaar, tenzij je natuurlijk van plan bent experimenten te doen met verschillende parameterwaarden.
Zoals anderen al hebben opgemerkt, is het geen goede gewoonte om een veld te hebben waarin geen gegevens maar een berekening worden opgeslagen. Het is de-normalisatie. In plaats daarvan houdt u de tabel genormaliseerd en laat u de database de berekeningen doen elke keer dat u deze nodig heeft:
SELECT id, budget, cost,
cost*1000 + budget*1 AS rank_score_calculated
FROM table_name
ORDER BY rank_score_calculated DESC
rank_score_calculated
wordt niet opgeslagen in het bovenstaande voorbeeld. Op deze manier hoeft u het berekende veld niet elke keer bij te werken wanneer een budget of een kostenpost wordt gewijzigd of een nieuwe rij wordt toegevoegd in de tabel.
Er is alleen een nadeel. Als de tabel erg groot is en je die zoekopdracht (en de berekening) door veel gebruikers en heel vaak nodig hebt, en de tabel wordt vaak bijgewerkt, dan kan het je database vertragen. In dat geval zou men moeten nadenken over het toevoegen van zo'n veld.
Het andere geval is wanneer men een absolute rank
nodig heeft over alle tabelrijen, zoals uw behoefte. Omdat MySQL geen "venster"-functies heeft, is het erg moeilijk om zo'n query in pure SQL te schrijven.)
De rangorde kan worden berekend met behulp van MySQL-variabelen
SELECT *
, @rownum:[email protected]+1 AS rank_calculated
FROM table_name
, (SELECT @rownum:=0) AS st
ORDER BY rank_score DESC
En als u die waarden in rank
wilt plaatsen , gebruik:
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 ;
De bovenstaande twee query's zijn geen pure SQL. U kunt de optie onderzoeken om naar een ander databasesysteem te gaan dat vensterfuncties ondersteunt, zoals Postgres, SQL-Server of Oracle.