Først ville jeg ændre budget
, cost
og rank_score
i heltal eller anden numerisk datatype og i stedet for
UPDATE table_name
SET rank_score = CONCAT(cost, budget) ;
Så ville du bruge:
UPDATE table_name
SET rank_score = cost * 1000 + budget * 1 ;
Det er nemmere da, da du ikke skal beskæftige dig med strengfunktioner og have noget som:
SELECT *
FROM table_name
WHERE (conditions...)
ORDER BY rank_score DESC
(Parentes:have én parameter (1000
) sat så højere end den anden (1
) svarer til at have en ordre på cost, budget
. Prøv dette for at kontrollere:
SELECT *
FROM table_name
ORDER BY cost DESC
, budget DESC
Så du kan godt droppe rank_score
alt i alt, medmindre du selvfølgelig planlægger at lave eksperimenter med forskellige parameterværdier.
Som andre har påpeget, er det ikke bedste praksis at have et felt, der ikke lagrer data, men en beregning. Det er denormalisering. I stedet holder du tabellen normaliseret og lader databasen udføre beregningerne, hver gang du har brug for den:
SELECT id, budget, cost,
cost*1000 + budget*1 AS rank_score_calculated
FROM table_name
ORDER BY rank_score_calculated DESC
rank_score_calculated
er ikke gemt i ovenstående eksempel. På denne måde behøver du ikke at opdatere det beregnede felt, hver gang et budget eller en omkostning ændres, eller en ny række tilføjes i tabellen.
Der er kun én ulempe. Hvis tabellen er virkelig stor, og du har brug for den forespørgsel (og beregningen) udført af mange brugere og meget ofte, og tabellen opdateres ret ofte, så kan det gøre din database langsommere. I så fald bør man begynde at tænke på at tilføje sådan et felt.
Det andet tilfælde er, når man har brug for en absolut rank
på tværs af alle tabelrækkerne, som dit behov. Fordi MySQL ikke har nogen "vindue"-funktioner, er det meget svært at skrive sådan en forespørgsel i ren SQL.)
Rangeringen kan beregnes ved hjælp af MySQL-variabler
SELECT *
, @rownum:[email protected]+1 AS rank_calculated
FROM table_name
, (SELECT @rownum:=0) AS st
ORDER BY rank_score DESC
Og hvis du vil sætte disse værdier i rank
, brug:
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 ;
Ovenstående to forespørgsler er ikke ren SQL. Du kan undersøge muligheden for at flytte til et andet daabase-system, der understøtter vinduesfunktioner, såsom Postgres, SQL-Server eller Oracle.