Per prima cosa, cambierei budget
, cost
e rank_score
in intero o altro tipo di dati numerico e invece di
UPDATE table_name
SET rank_score = CONCAT(cost, budget) ;
Quindi useresti:
UPDATE table_name
SET rank_score = cost * 1000 + budget * 1 ;
È più facile quindi perché non dovrai occuparti di funzioni di stringa e avere qualcosa come:
SELECT *
FROM table_name
WHERE (conditions...)
ORDER BY rank_score DESC
(Tra parentesi:avere un parametro (1000
) impostato così più alto dell'altro (1
) equivale ad avere un ordine di cost, budget
. Prova questo per controllare:
SELECT *
FROM table_name
ORDER BY cost DESC
, budget DESC
Quindi, puoi benissimo eliminare il rank_score
nel complesso, a meno che, ovviamente, non prevediate di fare esperimenti con vari valori di parametro.
Come altri hanno sottolineato, non è consigliabile avere un campo che non memorizza dati ma un calcolo. È denormalizzazione. Invece, mantieni la tabella normalizzata e lasci che il database faccia i calcoli ogni volta che ne hai bisogno:
SELECT id, budget, cost,
cost*1000 + budget*1 AS rank_score_calculated
FROM table_name
ORDER BY rank_score_calculated DESC
rank_score_calculated
non è memorizzato nell'esempio sopra. In questo modo, non dovrai aggiornare il campo calcolato ogni volta che viene modificato un budget o un costo o viene aggiunta una nuova riga nella tabella.
C'è solo un inconveniente. Se la tabella è davvero grande e hai bisogno di quella query (e del calcolo) eseguita da molti utenti e molto spesso, e la tabella viene aggiornata abbastanza spesso, allora potrebbe rallentare il tuo database. In tal caso, si dovrebbe iniziare a pensare di aggiungere un campo del genere.
L'altro caso è quando è necessario un rank
assoluto su tutte le righe della tabella, come la tua esigenza. Poiché MySQL non ha funzioni di "finestra", è molto difficile scrivere una query del genere in puro SQL.)
Il rango può essere calcolato utilizzando le variabili MySQL
SELECT *
, @rownum:[email protected]+1 AS rank_calculated
FROM table_name
, (SELECT @rownum:=0) AS st
ORDER BY rank_score DESC
E se vuoi inserire quei valori in rank
, usa:
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 ;
Le due query precedenti non sono puro SQL. Puoi esaminare l'opzione per passare a un altro sistema di database che supporti le funzioni della finestra, come Postgres, SQL-Server o Oracle.