1) Imagine ...
On voudrait faire une surprise au client 'Timken' et augmenter la quantité de tous ses articles de 1% pour toutes ses commandes du joli mois de mai de cette année ...
Comment faire ? La date ni le nom du client ne sont mentionnés dans la table contenir qui est à modifier !!!
Alors ??? hummm?? pourtant on n'a pas le droit de mettre plusieurs tables derrière UPDATE, n'est ce pas?.
Eh bien voilà la solution! : on utilise des jointures avec JOIN et le tour est joué
Oh! la belle requête ...
UPDATE gc_contenir
JOIN gc_commande ON gc_contenir.numCde = gc_commande.numCde --
JOIN gc_client ON gc_client.id = idClient --
SET qty=qty*1.01
WHERE YEAR(dateCde) = YEAR(CURDATE()) AND MONTH(dateCde) = 05 AND nomCli = 'Timken'
;
ATTENTION, Il n'y a qu'une seule table qui est effectivement mise à jour : gc_contenir !!
Remarquer en passant l'usage des fonctions YEAR(), MONTH() et CURDATE(), c'est mieux qu'un between tordu.
2) Autre (mauvaise) surprise pour les clients
Comment augmenter de 3% le prix des 10 articles les plus commandés ?
(re)Oh! la (re)belle requête ... encore plus sioux et compliquée à souhait qu'avant.
Observer le nommage de la table produite par la sous requête SELECT intégrée : TMP_meilleureVente
UPDATE gc_article
JOIN
(
SELECT refArt, sum(qty) FROM gc_contenir -- sum est optionnel car présent dans ORDER BY
GROUP BY refArt
ORDER BY sum(qty) DESC
LIMIT 0, 10 -- pour se limiter aux 10 premières lignes
) TMP_meilleureVente -- nommer la sous-requête intégrée
ON TMP_meilleureVente.refArt = gc_article.refArt
SET prixHTArt = prixHTArt*1.03
;
Remarquer en passant la sous-requête utilisée comme une table et (re)nommée en TMP_meilleureVente ; LIMIT permet de n'avoir que les 10 premières lignes
3) Dernier cas (après on va prendre un truc pour la tête)
Et si je veux modifier le champ champA d'une table Table_A avec le contenu du champ champB d'une autre table Table_B ?
On admettra que les deux tables sont jointes par les champs clés (primaires ou secondaires) champJointA et champJointB.
Observer la modification du champA : SET Table_A.champA = Table_B.champB
UPDATE Table_A
JOIN Table_B ON Table_B.champJointB=Table_A.champJointA
SET Table_A.champA = Table_B.champB
;
Vous suivez ?
4) Tiens ? non, encore un exemple (on est mûr pour le mur)
Admettons qu'il y ai un champ totalHT dans la commande, comment mettre ce champ à jour avec la somme des montants des articles?
TADAAAAA .... voilà la réponse (c'est pas minion, ça ?).
Observer : SET gc_commande.totalHT = TMP_Montants.montant
UPDATE gc_commande
JOIN (
SELECT cdeNum, sum(qty*prixHTArt) AS montant
FROM gc_contenir JOIN gc_article ON gc_c.refAret = gc_article.refArt
GROUP BY cdeNum
) TMP_Montants ON Montants.cdeNum = gc_commande.cdeNum
SET gc_commande.totalHT = TMP_Montants.montant
;
Y a quelqu'un ? Ah? non ! Ils sont tous morts. ... dommage, je m'amusais bien, pourtant.
La prochaine fois, je le fais en alsacien ou en breton, ou en corse.
yess
je suis le roi de la jointure