MySQL / SQL: Mise à jour avec sous-requête corrélée à partir de la table mise à jour elle-même

StackOverflow https://stackoverflow.com/questions/839938

Question

J'ai une question générique que je vais essayer d'expliquer à l'aide d'un exemple.

Dites que j'ai un tableau avec les champs: "id", "nom", "catégorie", "apparences". et "rapport"

L’idée est que j’ai plusieurs éléments, chacun lié à une seule catégorie et que "" apparaît" " plusieurs fois. Le champ de rapport doit inclure le pourcentage d'apparences de chaque élément par rapport au nombre total d'apparences d'éléments dans la catégorie.

En pseudo-code, il me faut ce qui suit:

  • Pour chaque catégorie
    trouver la somme totale des apparences pour les articles qui lui sont liés. Par exemple, cela peut être fait avec ( sélectionner la somme ("apparences") du groupe de tables par catégorie )

  • Pour chaque élément
    définissez la valeur du rapport en divisant les apparences de l'élément par la somme trouvée pour la catégorie ci-dessus

Maintenant, j'essaie de réaliser cela avec une seule requête de mise à jour, mais je n'arrive pas à le faire. Ce que je pensais devoir faire, c'est:

update Table T    
set T.ratio = T.appearances /   
(    
select sum(S.appearances)    
from Table S    
where S.id = T.id    
)

Mais MySQL n’accepte pas l’alias T dans la colonne update et je n’ai trouvé aucun autre moyen d’y parvenir.

Des idées?

Était-ce utile?

La solution

Après les deux réponses que j'ai reçues (aucune n'étant complète, j'ai donc écrit la mienne), ce que j'ai finalement fait est la suivante:

UPDATE Table AS target
INNER JOIN 
(
select category, appearances_sum
from Table T inner join (
    select category as cat, sum(appearances) as appearances_sum
    from Table
    group by cat
) as agg
where T.category  = agg.cat
group by category
) as source
ON target.category = source.category
SET target.probability = target.appearances / source.appearances_sum 

Cela fonctionne très rapidement. J'ai également essayé avec une sous-requête corrélée mais elle était beaucoup plus lente (ordres de grandeur), donc je m'en tiens à la jointure.

Autres conseils

Utilisez les jointures juste après UPDATE: Manuel de référence & # 8211; 13.2.11 Syntaxe UPDATE

alors UPDATE table1 interne rejoindre table2 sur .... set table1.foo = valeur où table2.bla = une autre valeur

Avec ce genre de choses, regardez toujours le manuel. MySql a un manuel de référence approprié, il ne devrait donc pas être aussi difficile d’obtenir la bonne syntaxe;)

Voici comment cela se fait dans mssql, je pense que mysql est identique ou similaire:

create table T (id int, ratio float, appearances int)
insert T values (1, null, 2)
insert T values (1, null, 3)

update T
set ratio = cast(appearances as float)/ agg.appearancesSum
from T join (
    select id, sum(appearances) as appearancesSum
    from T
    group by id
) as agg on t.id = agg.id
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top