INSERT INTO spéciaux
<h3>Simple et efficace pour faire des copies de tables ou des extractions</h3>
On va utiliser le résultat d'une requête pour insérer de nouveaux enregistrements dans une table existante.
[sql]
<ul> - INSERT INTO uneTable **SELECT une_requete** ;</li> </ul> </div> Attention, les champs issus de la requête doivent correspondre aux champs de la table ou, du moins, à ceux indiqués derrière **INSERT INTO uneTable**. Voir aussi ce lien vers <a href="http://www.w3schools.com/sql/sql_insert_into_select.asp">w3Schools::insert into select</a> <h3>Mieux, utilisons SELECT ... INTO ... FROM !!!</h3> Attention les yeux!! Si vous n'êtes pas prêt, ne lisez pas la suite, votre cerveau pourrait s'embrouiller. <sql> <ul> - SELECT [liste de champs ou *] <ul> - **INTO nouvelleTable**</li> - FROM [liste de tables]</li> - [suite normale de la requete SELECT]</li> </ul> ;</li> </ul> </div> La table **nouvelleTable** est créée à cette occasion contrairement à **INSERT INTO** où la table doit déjà exister. Voir aussi ce lien vers <a href="http://www.w3schools.com/sql/sql_select_into.asp">w3Schools::select into</a> (c'est pas le même) </div> <p><a href="#top">Top of page</a> ===== Update de fous ===== <abstract>Ou comment mettre à jour une table avec une contrainte sur une seconde table</abstract> <h3>1) Imagine ...</h3> 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 ... <br>Comment faire ? La date ni le nom du client ne sont mentionnés dans la table contenir qui est à modifier !!!<p> Alors ??? hummm?? pourtant on n'a pas le droit de mettre plusieurs tables derrière UPDATE, n'est ce pas?.<p> Eh bien voilà la solution! : on utilise des jointures avec JOIN et le tour est joué<br>Oh! la belle requête ...<p> <sql> <ul> - UPDATE Contenir <ul> - **JOIN Commande ON Contenir.numCde=Commande.numCde**</li> - **JOIN Client ON Client.id=idClient**</li> - SET qty=qty*1.01</li> - WHERE YEAR(dateCde)=YEAR(CURDATE()) AND MONTH(dateCde)=05 AND nomCli='Timken'</li> </ul> ;</li> </ul> </div> Remarquer en passant l'usage des fonctions YEAR(), MONTH() et CURDATE(), c'est mieux qu'un between tordu.<p> <h3>2) Autre (mauvaise) surprise pour les clients</h3> Comment augmenter de 3% le prix des 10 articles les plus commandés ? <br>(re)Oh! la (re)belle requête ... encore plus sioux et compliquée à souhait qu'avant.<p> <div class="code codeBg"> <ul> - UPDATE Article <ul> - JOIN <ul> - ( <ul> - SELECT refArt, sum(qty) FROM Contenir</li> - GROUP BY refArt </li> - ORDER BY sum(qty) DESC </li> - LIMIT 0, 10</li> </ul> ) **meilleureVente**</li> - ON **meilleureVente**.refArt=Article.refArt</li> </ul> - SET prixHTArt=prixHTArt*1.03</li> </ul> ;</li> </ul> </div> Remarquer en passant la sous requête utilisée comme une table et renommée en **meilleureVente** ; LIMIT permet de n'avoir que les 10 premières lignes<p> <h3>3) Dernier cas <span style="font-size:.7em">(après on va prendre un truc pour la tête)</span></h3> Et si je veux modifier le champ chTA d'une table TA avec le contenu du champ chTB d'une autre table TB ? <br>On admettra que les deux tables sont jointes par les champs clés (primaires ou secondaires) cjTA et cjTB.<p> <sql> UPDATE TA JOIN TB ON cjTB = cjTA SET **chTA=chTB** ;
Vous suivez ?
<h3>4) Tiens ? non, encore un exemple <span style="font-size:.7em">(on est mûr pour le mur)</span></h3>
Admettons qu'il y ai un champ totalHT dans la commande, comment mettre ce champ à jour avec la somme des montants des articles?
<br>TADAAAAA .... voilà la réponse (c'est pas minion, ça ?).<p>
<ul>
- UPDATE Commande
<ul> - JOIN ( <ul> - SELECT cdeNum, sum(qty*prixHTArt) AS montant </li> - FROM Contenir JOIN Article ON Contenir.refAret=Article.refArt </li> - GROUP BY cdeNum </li> </ul> ) montants ON montants.cdeNum=Commande.cdeNum</li> - SET **Commande.totalHT=montants.montant**</li> </ul> ;</li> </ul> </div>
Y a quelqu'un ? Ah? non ! Ils sont tous morts. ... dommage, je m'amusais bien, pourtant.
<br><span style="font-size:.7em">La prochaine fois, je le fais en alsacien ou en breton, ou en corse. <span style="font-size:.7em">yess <span style="font-size:.7em">je suis le roi de la jointure</span></span></span><p> </div> <p><a href="#top">Top of page</a>