Först skulle jag ändra budget
, cost
och rank_score
till heltal eller annan numerisk datatyp och istället för
UPDATE table_name
SET rank_score = CONCAT(cost, budget) ;
Då skulle du använda:
UPDATE table_name
SET rank_score = cost * 1000 + budget * 1 ;
Det är lättare då eftersom du inte behöver hantera strängfunktioner och att ha något som:
SELECT *
FROM table_name
WHERE (conditions...)
ORDER BY rank_score DESC
(Parentes:har en parameter (1000
) inställd så högre än den andra (1
) motsvarar att ha en beställning på cost, budget
. Prova detta för att kontrollera:
SELECT *
FROM table_name
ORDER BY cost DESC
, budget DESC
Så du kan väl släppa rank_score
sammantaget, såvida du naturligtvis inte planerar att göra experiment med olika parametervärden.
Som andra har påpekat är det inte bästa praxis att ha ett fält som inte lagrar data utan en beräkning. Det är avnormalisering. I stället håller du tabellen normaliserad och låter databasen göra beräkningarna varje gång du behöver 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
lagras inte i exemplet ovan. På så sätt behöver du inte uppdatera det beräknade fältet varje gång en budget eller en kostnad ändras eller en ny rad läggs till i tabellen.
Det finns bara en nackdel. Om tabellen är riktigt stor och du behöver den frågan (och beräkningen) göras av många användare och väldigt ofta, och tabellen uppdateras ganska ofta, kan det göra din databas långsammare. I så fall bör man börja fundera på att lägga till ett sådant fält.
Det andra fallet är när man behöver en absolut rank
över alla tabellrader, som ditt behov. Eftersom MySQL inte har några "fönster"-funktioner är det väldigt svårt att skriva en sådan fråga i ren SQL.)
Rangen kan beräknas med hjälp av MySQL-variabler
SELECT *
, @rownum:[email protected]+1 AS rank_calculated
FROM table_name
, (SELECT @rownum:=0) AS st
ORDER BY rank_score DESC
Och om du vill placera dessa värden i rank
, använd:
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 ;
Ovanstående två frågor är inte ren SQL. Du kan undersöka alternativet att flytta till ett annat daabase-system som stöder fönsterfunktioner, som Postgres, SQL-Server eller Oracle.