{"id":623,"date":"2013-06-20T17:18:51","date_gmt":"2013-06-20T15:18:51","guid":{"rendered":"http:\/\/www.lafabriquedecode.com\/blog\/?p=623"},"modified":"2013-06-20T17:18:51","modified_gmt":"2013-06-20T15:18:51","slug":"mysql-update-delete-jointures","status":"publish","type":"post","link":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/","title":{"rendered":"MySQL &#8211; update et delete avec des jointures"},"content":{"rendered":"<p>Le but de ce billet est de r\u00e9aliser des op\u00e9rations de mise \u00e0 jour ou de suppression \u00e0 l&rsquo;aide d&rsquo;une jointure, externe ou interne.<br \/>\nVoici le sch\u00e9ma qui nous sert de base de travail :<\/p>\n<ul>\n<li>une table client<\/li>\n<li>une table produit<\/li>\n<li>une table commande, avec deux contraintes de cl\u00e9 \u00e9trang\u00e8re partant vers chacune des tables<\/li>\n<\/ul>\n<p><a href=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2013\/06\/Hoan_Bridge.jpg\"><img loading=\"lazy\" src=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2013\/06\/Hoan_Bridge.jpg\" alt=\"Hoan_Bridge\" width=\"480\" height=\"320\" class=\"alignnone size-full wp-image-658\" srcset=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2013\/06\/Hoan_Bridge.jpg 480w, http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2013\/06\/Hoan_Bridge-300x200.jpg 300w\" sizes=\"(max-width: 480px) 100vw, 480px\" \/><\/a><\/p>\n<h1>Le SQL du sch\u00e9ma<\/h1>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\ncreate table client(\r\nid tinyint unsigned primary key auto_increment,\r\nnom varchar(30) not null,\r\nprenom varchar(20) not null);\r\n\r\ninsert into client (nom, prenom) values \r\n('Ferrandez', 'S\u00e9bastien'), ('Jambon', 'Paul');\r\n\r\ncreate table produit(\r\nid tinyint unsigned primary key auto_increment,\r\ndesignation varchar(30) not null,\r\nprix float (6,2) unsigned not null);\r\n\r\ninsert into produit (designation, prix) values \r\n('Mousse \u00e0 raser', 7.99), ('Stylo BIC', 4.99);\r\n\r\ncreate table commande (\r\nid tinyint unsigned primary key auto_increment, \r\nid_client tinyint unsigned , \r\nid_produit tinyint unsigned, \r\nquantite tinyint unsigned default 1,\r\ndate timestamp);\r\n\r\nalter table commande add constraint foreign key (id_client) \r\nreferences client(id);\r\n\r\nalter table commande add constraint foreign key (id_produit)\r\nreferences produit(id);\r\n\r\ninsert into commande(id_client,id_produit, quantite )\r\nvalues (1,1,2), (1,2,1), (2,2,1), (2,1,2);\r\n<\/pre>\n<h1>Les jointures, externes et internes<\/h1>\n<p>Le principe de la jointure est trivial, on cr\u00e9e comme une sorte de \u00ab\u00a0pont\u00a0\u00bb entre au moins 2 tables selon une condition qu&rsquo;on va tr\u00e8s simplement appeler \u00ab\u00a0condition de jointure\u00a0\u00bb. Une condition de jointure n&rsquo;est pas forc\u00e9ment une clause d&rsquo;\u00e9galit\u00e9 !<\/p>\n<p>Prenons l&rsquo;exemple de deux tables sans rapport quelconque :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\ncreate table eleve (nom varchar(20), age tinyint unsigned);\r\ninsert into eleve values ('Ferrandez', 10), ('Lucas', 30);\r\ncreate table produit (nom varchar(20), prix float(6,2) unsigned);\r\ninsert into produit values ('iPhone5', 499), ('Jambon', 10);\r\n<\/pre>\n<p>Qu&rsquo;est-ce qui nous emp\u00eache de faire une jointure entre un \u00e9l\u00e8ve et un produit bas\u00e9 sur l&rsquo;\u00e9galit\u00e9 de valeur de l&rsquo;\u00e2ge de l&rsquo;\u00e9l\u00e8ve et du prix du produit ?<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT * \r\nFROM  eleve \r\nINNER JOIN produit ON ( eleve.age = produit.prix ) \r\n<\/pre>\n<p>Nous obtenons<\/p>\n<pre>\r\n+-----------+------+--------+-------+\r\n| nom       | age  | nom    | prix  |\r\n+-----------+------+--------+-------+\r\n| Ferrandez |   10 | Jambon | 10.00 |\r\n+-----------+------+--------+-------+\r\n1 row in set (0.00 sec)\r\n<\/pre>\n<p>Une jointure ne se fait pas uniquement sur la base d&rsquo;une \u00e9galit\u00e9 de valeur, on peut utiliser d&rsquo;autres op\u00e9rateurs arithm\u00e9tiques :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT * \r\nFROM  eleve\r\nINNER JOIN produit ON ( eleve.age &lt;= produit.prix ) \r\n<\/pre>\n<p>Celle-ci remontera les tuples suivants :<\/p>\n<pre>\r\n+-----------+------+---------+--------+\r\n| nom       | age  | nom     | prix   |\r\n+-----------+------+---------+--------+\r\n| Ferrandez |   10 | iPhone5 | 499.00 |\r\n| Lucas     |   30 | iPhone5 | 499.00 |\r\n| Ferrandez |   10 | Jambon  |  10.00 |\r\n+-----------+------+---------+--------+\r\n3 rows in set (0.00 sec)   \r\n<\/pre>\n<p>Et pire, qu&rsquo;est-ce qui nous emp\u00eache de faire une jointure sur des champs qui n&rsquo;ont pas le m\u00eame type de donn\u00e9es (horreur !) :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT * \r\nFROM  eleve\r\nINNER JOIN produit ON ( eleve.age &lt;= produit.nom ) \r\n<\/pre>\n<p>Si on a le droit de faire \u00e7a, c&rsquo;est que l&rsquo;optimiseur MySQL effectue des conversions de type pour effectuer des comparaisons (diff\u00e9rence, \u00e9galit\u00e9 etc.). Mais recentrons-nous sur le sujet du billet ! Une requ\u00eate de jointure externe, contrairement aux internes, retourne \u00e0 la fois les correspondances (c&rsquo;est \u00e0 dire, les enregistrements satisfaisant la clause de jointure) et les non-correspondances (celles qui ne la satisfont pas). Voyons ce que donne :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT * \r\nFROM  eleve \r\nLEFT JOIN produit ON ( eleve.age = produit.prix ) \r\n<\/pre>\n<pre>\r\n+-----------+------+--------+-------+\r\n| nom       | age  | nom    | prix  |\r\n+-----------+------+--------+-------+\r\n| Ferrandez |   10 | Jambon | 10.00 |\r\n| Lucas     |   30 | <strong>NULL<\/strong>   |  <strong>NULL<\/strong> |\r\n+-----------+------+--------+-------+\r\n2 rows in set (0.00 sec)\r\n<\/pre>\n<p>Les non-correspondances sont signal\u00e9es par la pr\u00e9sence du marqueur NULL. Si vous choisissez de les remonter, rien de plus facile :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nSELECT eleve.*\r\nFROM  eleve \r\nLEFT JOIN produit ON ( eleve.age = produit.prix ) \r\nWHERE produit.prix IS NULL\r\n<\/pre>\n<p>Notez bien que le m\u00eame test, mais sur <strong>produit.nom IS NULL<\/strong> aurait \u00e9galement fonctionn\u00e9 !<br \/>\nBref, nous savons maintenant ce qu&rsquo;est une jointure interne (que ce qui correspond) et une jointure externe (ce qui correspond + ce qui ne correspond pas).<\/p>\n<h1>La mise \u00e0 jour<\/h1>\n<p>Nous allons mettre \u00e0 jour les commandes du client S\u00e9bastien Ferrandez en disant qu&rsquo;elles ont eu lieu le 24 D\u00e9cembre 2013 \u00e0 23:59:59 :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nUPDATE commande INNER JOIN client\r\nON (commande.id_client = client.id)\r\nSET commande.date = '2013-12-24 23:59:59'\r\nWHERE client. nom = 'ferrandez'\r\nAND client.prenom = 'sebastien'\r\n<\/pre>\n<p>Notez que nous sommes en collation latin1_general_ci et que nous ne tenons donc compte ni des accents ni des majuscules&#8230;<br \/>\nSi d&rsquo;aventure vous souhaitez modifier d&rsquo;autres champs (y compris dans la table client, pas que commande !), s\u00e9parez les dans SET avec des virgules !<\/p>\n<p>Vous pouvez tr\u00e8s bien utiliser la jointure externe pour mettre a jour des enregistrements ne se trouvant pas dans la table commande (nous aurions par exemple dans la table client un champ bool\u00e9en <em>A_DEJA_COMMANDE<\/em> que nous mettrions \u00e0 0 si aucune commande n&rsquo;\u00e9tait trouv\u00e9e pour celui-ci).<\/p>\n<h1>La suppression<\/h1>\n<p>Ins\u00e9rons un nouveau tuple dans client :<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\ninsert into client (nom, prenom) values ('Diego', 'Miguel');\r\n<\/pre>\n<p>Et effectuons sa suppression imm\u00e9diate en disant \u00ab\u00a0J&rsquo;efface les clients qui n&rsquo;ont pas pass\u00e9 de commande\u00a0\u00bb<\/p>\n<pre class=\"brush: sql; title: ; notranslate\" title=\"\">\r\nDELETE client.* FROM client\r\nLEFT OUTER JOIN commande \r\nON ( client.id = commande.id_client )\r\nWHERE commande.id_client IS NULL\r\n<\/pre>\n<p>N&rsquo;oubliez pas que vous n&rsquo;\u00eates absolument pas limit\u00e9s \u00e0 UNE jointure et que vous pouvez tr\u00e8s bien alterner jointures externes et internes dans la m\u00eame requ\u00eate ! Entra\u00eenez-vous sur des petits sch\u00e9mas tout simples du m\u00eame genre que celui que nous avons vu dans ce billet et tout \u00e7a n&rsquo;aura bient\u00f4t plus de secret pour vous !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Le but de ce billet est de r\u00e9aliser des op\u00e9rations de mise \u00e0 jour ou de suppression \u00e0 l&rsquo;aide d&rsquo;une jointure, externe ou interne. Voici le sch\u00e9ma qui nous sert de base de travail : une table client une table produit une table commande, avec deux contraintes de cl\u00e9 \u00e9trang\u00e8re partant vers chacune des tables [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[2],"tags":[49,63,48],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.6.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>MySQL - update et delete avec des jointures - La Fabrique de code - Tech blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MySQL - update et delete avec des jointures - La Fabrique de code - Tech blog\" \/>\n<meta property=\"og:description\" content=\"Le but de ce billet est de r\u00e9aliser des op\u00e9rations de mise \u00e0 jour ou de suppression \u00e0 l&rsquo;aide d&rsquo;une jointure, externe ou interne. Voici le sch\u00e9ma qui nous sert de base de travail : une table client une table produit une table commande, avec deux contraintes de cl\u00e9 \u00e9trang\u00e8re partant vers chacune des tables [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/\" \/>\n<meta property=\"og:site_name\" content=\"La Fabrique de code - Tech blog\" \/>\n<meta property=\"article:published_time\" content=\"2013-06-20T15:18:51+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2013\/06\/Hoan_Bridge.jpg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary\" \/>\n<meta name=\"twitter:creator\" content=\"@LaFabrique2Code\" \/>\n<meta name=\"twitter:site\" content=\"@LaFabrique2Code\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/\",\"url\":\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/\",\"name\":\"MySQL - update et delete avec des jointures - La Fabrique de code - Tech blog\",\"isPartOf\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#website\"},\"datePublished\":\"2013-06-20T15:18:51+00:00\",\"dateModified\":\"2013-06-20T15:18:51+00:00\",\"author\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162\"},\"breadcrumb\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"http:\/\/www.lafabriquedecode.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"MySQL &#8211; update et delete avec des jointures\"}]},{\"@type\":\"WebSite\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#website\",\"url\":\"http:\/\/www.lafabriquedecode.com\/blog\/\",\"name\":\"La Fabrique de code - Tech blog\",\"description\":\"PHP objet, MySQL, Design Patterns, OOP...et plus !\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\/\/www.lafabriquedecode.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Person\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g\",\"contentUrl\":\"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g\",\"caption\":\"admin\"},\"url\":\"http:\/\/www.lafabriquedecode.com\/blog\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"MySQL - update et delete avec des jointures - La Fabrique de code - Tech blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/","og_locale":"fr_FR","og_type":"article","og_title":"MySQL - update et delete avec des jointures - La Fabrique de code - Tech blog","og_description":"Le but de ce billet est de r\u00e9aliser des op\u00e9rations de mise \u00e0 jour ou de suppression \u00e0 l&rsquo;aide d&rsquo;une jointure, externe ou interne. Voici le sch\u00e9ma qui nous sert de base de travail : une table client une table produit une table commande, avec deux contraintes de cl\u00e9 \u00e9trang\u00e8re partant vers chacune des tables [&hellip;]","og_url":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/","og_site_name":"La Fabrique de code - Tech blog","article_published_time":"2013-06-20T15:18:51+00:00","og_image":[{"url":"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2013\/06\/Hoan_Bridge.jpg"}],"author":"admin","twitter_card":"summary","twitter_creator":"@LaFabrique2Code","twitter_site":"@LaFabrique2Code","twitter_misc":{"\u00c9crit par":"admin","Dur\u00e9e de lecture estim\u00e9e":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/","url":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/","name":"MySQL - update et delete avec des jointures - La Fabrique de code - Tech blog","isPartOf":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/#website"},"datePublished":"2013-06-20T15:18:51+00:00","dateModified":"2013-06-20T15:18:51+00:00","author":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162"},"breadcrumb":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/"]}]},{"@type":"BreadcrumbList","@id":"http:\/\/www.lafabriquedecode.com\/blog\/2013\/06\/mysql-update-delete-jointures\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"http:\/\/www.lafabriquedecode.com\/blog\/"},{"@type":"ListItem","position":2,"name":"MySQL &#8211; update et delete avec des jointures"}]},{"@type":"WebSite","@id":"http:\/\/www.lafabriquedecode.com\/blog\/#website","url":"http:\/\/www.lafabriquedecode.com\/blog\/","name":"La Fabrique de code - Tech blog","description":"PHP objet, MySQL, Design Patterns, OOP...et plus !","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/www.lafabriquedecode.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Person","@id":"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162","name":"admin","image":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/image\/","url":"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g","contentUrl":"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g","caption":"admin"},"url":"http:\/\/www.lafabriquedecode.com\/blog\/author\/admin\/"}]}},"_links":{"self":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/623"}],"collection":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/comments?post=623"}],"version-history":[{"count":39,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/623\/revisions"}],"predecessor-version":[{"id":663,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/623\/revisions\/663"}],"wp:attachment":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/media?parent=623"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/categories?post=623"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/tags?post=623"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}