sql >> Database teknologi >  >> RDS >> Mysql

MySQL Hjælp:Optimer opdateringsforespørgsel, der angiver rangering i henhold til rækkefølgen af ​​en anden kolonne

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.



  1. Udførelse af rekursive lagrede procedurer i MYSQL for at få hierarkiske data

  2. Sådan vælger du hver n'te række i mySQL fra n

  3. Beverly Hills 90210 og ZIP+4:Håndtering af adresser i datamodeller

  4. Forhindrer oci_bind_by_name SQL-injektion sikkert?