{"id":95044,"date":"2022-11-12T01:59:14","date_gmt":"2022-11-12T01:59:14","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=95044"},"modified":"2022-11-23T01:34:18","modified_gmt":"2022-11-23T01:34:18","slug":"introducing-the-mysql-delete-statement","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/mysql\/introducing-the-mysql-delete-statement\/","title":{"rendered":"Introducing the MySQL DELETE statement"},"content":{"rendered":"<p style=\"margin: 0in; font-family: Calibri; font-size: 11.0pt;\"><p><strong>This article is part of Robert Sheldon's continuing series on Learning MySQL. To see all of the items in the series, <a href=\"https:\/\/www.red-gate.com\/simple-talk\/mysql-coding-basics\/\">click here<\/a>.<\/strong><\/p>\n<\/p>\n<h2>Preparing your MySQL environment<\/h2>\n<p>As with the previous few articles, I used the same database and tables for the examples in this article (the <code>travel<\/code> database and the <code>manufacturers<\/code> and <code>airplanes<\/code> tables). In this case, however, I recommend that you start from scratch and rebuild the database and tables to keep things simple for this article. To set up the database, run the following script:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">DROP DATABASE IF EXISTS travel;\r\n\r\nCREATE DATABASE travel;\r\n\r\nUSE travel;\r\n\r\nCREATE TABLE manufacturers (\r\n  manufacturer_id INT UNSIGNED NOT NULL AUTO_INCREMENT,\r\n  manufacturer VARCHAR(50) NOT NULL,\r\n  create_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\r\n  last_update TIMESTAMP NOT NULL \r\n    DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\r\n  PRIMARY KEY (manufacturer_id) )\r\nENGINE=InnoDB AUTO_INCREMENT=1001;\r\n\r\nCREATE TABLE airplanes (\r\n  plane_id INT UNSIGNED NOT NULL AUTO_INCREMENT,\r\n  plane VARCHAR(50) NOT NULL,\r\n  manufacturer_id INT UNSIGNED NOT NULL,\r\n  engine_type VARCHAR(50) NOT NULL,\r\n  engine_count TINYINT NOT NULL,\r\n  max_weight MEDIUMINT UNSIGNED NOT NULL,\r\n  wingspan DECIMAL(5,2) NOT NULL,\r\n  plane_length DECIMAL(5,2) NOT NULL,\r\n  parking_area INT GENERATED ALWAYS AS ((wingspan * plane_length)) STORED,\r\n  icao_code CHAR(4) NOT NULL,\r\n  create_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\r\n  last_update TIMESTAMP NOT NULL \r\n    DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\r\n  PRIMARY KEY (plane_id),\r\n  CONSTRAINT fk_manufacturer_id FOREIGN KEY (manufacturer_id) \r\n    REFERENCES manufacturers (manufacturer_id) ) \r\nENGINE=InnoDB AUTO_INCREMENT=101;<\/pre>\n<p>Once you\u2019ve created the database, you can add the sample data you\u2019ll need to follow along with the exercises in this article. Start by running the following <code>INSERT<\/code> statement to add data to the <code>manufacturers<\/code> table:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">INSERT INTO manufacturers (manufacturer)\r\nVALUES ('Bombardier'), ('Beagle Aircraft Limited');\r\n\r\nSELECT *\r\nFROM   manufacturers;<\/pre>\n<p>The statement adds two rows to the <code>manufacturers<\/code> table and outputs those rows. The <code>manufacturer_id<\/code> column in those rows should have been assigned the values <code>1001<\/code> and <code>1002<\/code>.<\/p>\n<p>After you confirm the data in the <code>manufacturers<\/code> table, you should run the following <code>INSERT<\/code> statement, which populates the <code>airplanes<\/code> table:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">INSERT INTO airplanes \r\n  (plane, manufacturer_id, engine_type, engine_count, \r\n    wingspan, plane_length, max_weight, icao_code)\r\nVALUES\r\n  ('Learjet 24',1001,'Jet',2,35.58,43.25,13000,'LJ24'),\r\n  ('Learjet 24A',1001,'Jet',2,35.58,43.25,12499,'LJ24'),\r\n  ('Challenger (BD-100-1A10) 300',1001,'Jet',2,63.83,68.75,38850,'CL30'),\r\n  ('Challenger (BD-100-1A10) 350',1001,'Jet',2,69,68.75,40600,'CL30'),\r\n  ('Challenger (CL-600-1A11) 600',1001,'Jet',2,64.33,68.42,36000,'CL60'),\r\n  ('Challenger (CL-600-2A12) 601',1001,'Jet',2,64.33,68.42,42100,'CL60'),\r\n  ('A.109 Airedale',1002,'piston',1,36.33,26.33,2750,'AIRD'),\r\n  ('A.61 Terrier',1002,'piston',1,36,23.25,2400,'AUS6'),\r\n  ('B.121 Pup',1002,'piston',1,31,23.17,1600,'PUP'),\r\n  ('B.206',1002,'piston',2,55,33.67,7500,'BASS'),\r\n  ('D.4-108',1002,'piston',1,36,23.33,1900,'D4'),\r\n  ('D.5-108 Husky',1002,'piston',1,36,23.17,2400,'D5');\r\n\r\nSELECT *\r\nFROM   airplanes;<\/pre>\n<p>The values <code>1001<\/code> and <code>1002<\/code> from the <code>manufacturers<\/code> table provide the foreign key values for the <code>manufacturer_id<\/code> column in the <code>airplanes<\/code> table. After you run the second <code>INSERT<\/code> statement, the SELECT query will let you confirm that 12 rows have been added to the airplanes table. The first row should have been assigned <code>101<\/code> as the <code>plane_id<\/code> value, and the <code>plane_id<\/code> values for the other rows should have been incremented accordingly.<\/p>\n<h2>The <code><strong>DELETE<\/strong><\/code> statement syntax<\/h2>\n<p>The basic syntax for the <code>DELETE<\/code> statement is fairly straightforward and includes many of the same elements you saw in the other DML statements (<a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/mysql\/introducing-the-mysql-insert-statement\/\">INSERT<\/a> and UPDATE article links):<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">DELETE [IGNORE] FROM table_name\r\n[WHERE where_condition]\r\n[ORDER BY order_list]\r\n[LIMIT row_count]<\/pre>\n<p>The syntax shown here does not include all supported statement components, but it provides the basic elements you need to know to get started with the <code>DELETE<\/code> statement. You can refer to MySQL topic <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/delete.html\">DELETE Statement<\/a> for the complete syntax. In the meantime, here\u2019s a breakdown of the statement\u2019s clauses, as I\u2019ve shown in the syntax:<\/p>\n<ul>\n<li>The <code>DELETE<\/code> clause, which includes the <code>FROM<\/code> subclause, is the only mandatory clause in the <code>DELETE<\/code> statement. The clause identifies that table from which the data will be deleted. You can specify multiple tables, which involves defining join conditions, but my focus in this article is on single-table deletes. The <code>DELETE<\/code> clause also supports the use of the <code>IGNORE<\/code> modifier for returning a warning message, rather than an error, if an issue arises.<\/li>\n<li>The <code>WHERE<\/code> clause determines which rows to delete, based on one or more search conditions. The clause works much like the <code>WHERE<\/code> clause in <code>SELECT<\/code> and <code>UPDATE<\/code> statements. Although the <code>WHERE<\/code> clause is optional, you should be very careful running a <code>DELETE<\/code> statement that does not include one. Without a <code>WHERE<\/code> clause, the statement will delete every row in the target table, unless the <code>LIMIT<\/code> clause is included.<\/li>\n<li>The <code>ORDER<\/code> <code>BY<\/code> clause specifies the order that rows should be deleted. This clause is used primarily in conjunction with the <code>LIMIT<\/code> clause to help better direct which rows should be removed. The <code>ORDER<\/code> <code>BY<\/code> clause is similar to the one you saw in the <code>SELECT<\/code> and <code>UPDATE<\/code> statements. The clause is optional and cannot be used for multi-table deletes.<\/li>\n<li>The <code>LIMIT<\/code> clause limits the number of rows that will be deleted. When used with the <code>ORDER<\/code> <code>BY<\/code> clause, the deleted rows will be determined by the sort order specified by that clause. As with the <code>ORDER<\/code> <code>BY<\/code> clause, the <code>LIMIT<\/code> clause is optional and cannot be used for multi-table deletes.<\/li>\n<\/ul>\n<p>As you work through the examples in this article, you\u2019ll get a better sense of how the various statement elements work together. That said, the clauses are, for the most part, self-explanatory, and for most uses, you should have little trouble figuring out how they work. The larger concern is that you can lose a lot of data if you\u2019re not careful when using this statement, so always exercise caution, and be sure that all data is fully protected. Above all, make sure you\u2019re not working in a production environment when learning how to use the <code>DELETE<\/code> statement.<\/p>\n<h2>Deleting data from a MySQL table<\/h2>\n<p>As noted above, the <code>DELETE<\/code> clause is the only mandatory clause in a <code>DELETE<\/code> statement. If you run a <code>DELETE<\/code> statement with only this clause, it will remove all of the data from the target table\u2014a consideration that should not be taken lightly. If you determine that this <em>is<\/em> what you want to do, you need only specify the <code>DELETE<\/code> and <code>FROM<\/code> keywords, followed by the table name, as in the following example:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">DELETE FROM airplanes;<\/pre>\n<p>The statement will delete all data from the <code>airplanes<\/code> table, unless safe mode is enabled. Safe mode is typically enabled by default on a MySQL instance to help limit the possibility of updating or deleting all data in a table.<\/p>\n<p>Much the same as described for the UPDATE statement, if safe mode is enabled on your MySQL instance, you\u2019ll receive the following error message when you try to run the above statement:<\/p>\n<p><code>Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. To disable safe mode, toggle the option in Preferences -&gt; SQL Editor and reconnect.<\/code><\/p>\n<p>When safe mode is enabled, you cannot run a <code>DELETE<\/code> statement without a <code>WHERE<\/code> clause that does not specify a key column in the WHERE clause criteria, unless you include a <code>LIMIT<\/code> clause. This helps to ensure that you don\u2019t inadvertently delete a table full of data. You can disable safe mode (as the error message suggests) by setting the server properties or by temporarily disabling safe mode when you run the <code>DELETE<\/code> statement. The temporary approach is usually the safest.<\/p>\n<p>To temporarily disable safe mode, use a <code>SET<\/code> statement to change the <code>SQL_SAFE_UPDATES<\/code> system variable to <code>0<\/code> prior to running your <code>DELETE<\/code> statement and then set the variable to <code>1<\/code> after running the statement, as shown in the following example:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SET SQL_SAFE_UPDATES = 0;\r\n\r\nDELETE FROM airplanes;\r\n\r\nSET SQL_SAFE_UPDATES = 1;<\/pre>\n<p>The <code>SET<\/code> statements toggle the system variable off and then on during the current session. When taking this approach, be aware that if your <code>DELETE<\/code> statement generates an error, statement execution will stop and the second <code>SET<\/code> statement will not execute, so make sure you run this statement to reset the <code>SQL_SAFE_UPDATES<\/code> variable to <code>1<\/code>. Also note that the <code>SET<\/code> statement supports the optional <code>GLOBAL<\/code> modifier, which defines a variable at the global scope. However, I recommend that you do <em>not<\/em> use this option when disabling safe deletes. It is less risky to disable safe mode at the session level to avoid any inadvertent data modifications. Use <code>GLOBAL<\/code> only if it\u2019s essential in your situation.<\/p>\n<p>Once safe mode is disabled, you should be able to run your <code>DELETE<\/code> statement without generating an error. After you do, you can confirm your changes with a simple <code>SELECT<\/code> statement that retrieves all data from the <code>airplanes<\/code> table. The statement should return no rows.<\/p>\n<h2>Adding a <code><strong>WHERE<\/strong><\/code> clause to your <code><strong>DELETE<\/strong><\/code> statement<\/h2>\n<p>In most cases, you\u2019ll want to include a <code>WHERE<\/code> clause in your <code>DELETE<\/code> statements so you can target which rows in a table should be deleted (as opposed to deleting all rows). The <code>WHERE<\/code> clause defines one or more search conditions that specify exactly what data to delete. To see how this works, you should first add the data back to the <code>airplanes<\/code> table (assuming you\u2019re trying out these examples):<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">INSERT INTO airplanes \r\n  (plane, manufacturer_id, engine_type, engine_count, \r\n    wingspan, plane_length, max_weight, icao_code)\r\nVALUES\r\n  ('Learjet 24',1001,'Jet',2,35.58,43.25,13000,'LJ24'),\r\n  ('Learjet 24A',1001,'Jet',2,35.58,43.25,12499,'LJ24'),\r\n  ('Challenger (BD-100-1A10) 300'\r\n               ,1001,'Jet',2,63.83,68.75,38850,'CL30'),\r\n  ('Challenger (BD-100-1A10) 350'\r\n                ,1001,'Jet',2,69,68.75,40600,'CL30'),\r\n  ('Challenger (CL-600-1A11) 600'\r\n                ,1001,'Jet',2,64.33,68.42,36000,'CL60'),\r\n  ('Challenger (CL-600-2A12) 601'\r\n               ,1001,'Jet',2,64.33,68.42,42100,'CL60'),\r\n  ('A.109 Airedale',1002,'piston',1,36.33,26.33,2750,'AIRD'),\r\n  ('A.61 Terrier',1002,'piston',1,36,23.25,2400,'AUS6'),\r\n  ('B.121 Pup',1002,'piston',1,31,23.17,1600,'PUP'),\r\n  ('B.206',1002,'piston',2,55,33.67,7500,'BASS'),\r\n  ('D.4-108',1002,'piston',1,36,23.33,1900,'D4'),\r\n  ('D.5-108 Husky',1002,'piston',1,36,23.17,2400,'D5');\r\n\r\nSELECT *\r\nFROM airplanes;<\/pre>\n<p>Confirm that the data has been re-added to the <code>airplanes<\/code> table by looking at the output of the <code>SELECT<\/code> statement. The table should now be populated with the same 12 rows, with one notable difference. The first <code>plane_id<\/code> value is now <code>113<\/code> rather than <code>101<\/code> because MySQL tracks the last auto-incremented value that was assigned to a row, even if that row has been deleted.<\/p>\n<p>After you\u2019ve inserted the data into the <code>airplanes<\/code> table, you can run the following <code>DELETE<\/code> statement, which includes a basic <code>WHERE<\/code> clause:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">DELETE FROM airplanes\r\nWHERE icao_code = 'pup';<\/pre>\n<p>The search condition specifies that the <code>icao_code<\/code> value must equal <code>pup<\/code> for a row to be deleted. However, if you try to run this statement and safe mode is enabled, MySQL will again return error 1175:<\/p>\n<p><code>Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. To disable safe mode, toggle the option in Preferences -&gt; SQL Editor and reconnect.<\/code><\/p>\n<p>MySQL returns this error because the <code>WHERE<\/code> clause does not include a key column in its search condition. To get around this, you can again temporarily disable safe mode at the session level:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SET SQL_SAFE_UPDATES = 0;\r\n\r\nDELETE FROM airplanes\r\nWHERE icao_code = 'pup';\r\n\r\nSET SQL_SAFE_UPDATES = 1;<\/pre>\n<p>If you query the <code>airplanes<\/code> table after running these statements, the table should now include only 11 rows rather than 12. Only one row satisfied the search condition, so only that row was deleted.<\/p>\n<p>In cases where you specifically know what rows to delete, you should try to use a key column in your search condition to avoid having to disable safe mode. For example, the row deleted in the previous example had a <code>plane_id<\/code> value of <code>121<\/code>. As a result, you could have recast the <code>DELETE<\/code> statement as follows:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">DELETE FROM airplanes\r\nWHERE plane_id = 121;<\/pre>\n<p>Of course, it\u2019s not always practical to use a key column, in which case, you should define the <code>WHERE<\/code> clause in a way that best suits your situation, even if it means specifying multiple search conditions, as in the following example:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SET SQL_SAFE_UPDATES = 0;\r\n\r\nDELETE FROM airplanes\r\nWHERE engine_type = 'piston' AND max_weight &lt; 2500 ;\r\n\r\nSET SQL_SAFE_UPDATES = 1;<\/pre>\n<p>Because the <code>WHERE<\/code> clause contains no key column, safe mode must again be disabled during the session.<\/p>\n<p>The <code>WHERE<\/code> clause itself includes two search conditions. The first one specifies that the <code>engine_type<\/code> value must be <code>piston<\/code>, and the second one specifies that the <code>max_weight<\/code> value must be less that <code>2500<\/code>. The search conditions are connected by the <code>AND<\/code> logical operator, which means that both conditions must evaluate to true for a row to be deleted.<\/p>\n<p>In this case, several rows matched both search conditions, so they were all removed from the <code>airplanes<\/code> table. If you query the table, you should find that it now includes only eight rows.<\/p>\n<h2>Adding <code><strong>ORDER<\/strong><\/code> <code><strong>BY<\/strong><\/code> and <code><strong>LIMIT<\/strong><\/code> clauses to your <code><strong>DELETE<\/strong><\/code> statement<\/h2>\n<p>Together, the <code>ORDER<\/code> <code>BY<\/code> and <code>LIMIT<\/code> clauses help you better control how rows are deleted from a table. To see how this works, start be adding a row back into the <code>airplanes<\/code> table:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">INSERT INTO airplanes \r\n  (plane, manufacturer_id, engine_type, engine_count, \r\n    wingspan, plane_length, max_weight, icao_code)\r\nVALUES\r\n  ('D.4-108',1002,'piston',1,36,23.33,1900,'D4');<\/pre>\n<p>Because this row is being added separately from when the previous rows were added, it will have a different <code>create_date<\/code> value from the other rows. (The value is a timestamp.) You can use this value to single out the row when building your <code>DELETE<\/code> statement:<\/p>\n<pre class=\"lang:none theme:none\">DELETE FROM airplanes\r\nORDER BY create_date DESC\r\nLIMIT 1;<\/pre>\n<p>Notice that the statement includes no <code>WHERE<\/code> clause with a key column and that there are no <code>SET<\/code> statements. You can get away with this here because the <code>DELETE<\/code> statement includes a <code>LIMIT<\/code> clause. If necessary, you can include a <code>WHERE<\/code> clause with the <code>ORDER<\/code> <code>BY<\/code> and <code>LIMIT<\/code> clauses, but it\u2019s not needed in this case.<\/p>\n<p>The <code>ORDER<\/code> <code>BY<\/code> clause specifies that the rows should be deleted based on the <code>create_date<\/code> values, sorted in descending order. This ensures that the last row inserted is the first row deleted, assuming it has a unique <code>create_date<\/code> value. The <code>LIMIT<\/code> clause then specifies that only one row should be deleted. This will be the first row as it is determined by the <code>ORDER<\/code> <code>BY<\/code> clause. You might also consider this approach when deleting archived data, except that you would likely specify an amount other than 1 in the <code>LIMIT<\/code> clause, such as 100, 1000, or another value.<\/p>\n<p>It&#8217;s hard to say how often you\u2019ll use the <code>ORDER<\/code> <code>BY<\/code> and <code>LIMIT<\/code> clauses in your queries. But it\u2019s good to know that you have this option if you want to apply similar logic when deleting data from your database tables.<\/p>\n<p>You can also use these clauses independently of each other. For example, you might use the <code>LIMIT<\/code> clause when you need to delete a large number of rows from a table and you\u2019re concerned about the impact on database performance. Instead of deleting all the rows at once, you can delete them in batches based on the number of rows specified in the <code>LIMIT<\/code> clause. Then you can simply rerun the <code>DELETE<\/code> statement until all the target rows have been removed.<\/p>\n<h2>Using the <code><strong>IGNORE<\/strong><\/code> modifier in your <code><strong>DELETE<\/strong><\/code> statement<\/h2>\n<p>As noted earlier, the <code>DELETE<\/code> statement supports the use of the optional <code>IGNORE<\/code> modifier, which you also saw in the <code>INSERT<\/code> and <code>UPDATE<\/code> statements. When <code>IGNORE<\/code> is used, your <code>DELETE<\/code> statement will return a warning rather than an error if an issue arises. In addition, MySQL will continue with the statement execution. If you don\u2019t use <code>IGNORE<\/code>, MySQL will return an error and stop all statement execution, including any statements in the batch that follow the <code>DELETE<\/code> statement.<\/p>\n<p>To see how this works, start by running the following <code>INSERT<\/code> statement, which adds several rows to the <code>manufacturers<\/code> table:<\/p>\n<pre class=\"lang:none theme:none\">INSERT INTO manufacturers (manufacturer)\r\nVALUES ('Airbus'), ('Beechcraft'), ('Cessna'), ('Piper');\r\n\r\nSELECT *\r\nFROM   manufacturers;<\/pre>\n<p>From the output of this batch, you should find that the Airbus row has a <code>manufacturer_id<\/code> value of <code>1003<\/code>. You will use this value as the foreign key value when you add a row to the <code>airplanes<\/code> table for an Airbus plane. To add the row, run the following <code>INSERT<\/code> statement:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">INSERT INTO airplanes \r\n  (plane, manufacturer_id, engine_type, engine_count, \r\n    wingspan, plane_length, max_weight, icao_code)\r\nVALUES\r\n('A220-100',1003,'Jet',2,115.08,114.75,134000,'BCS1');<\/pre>\n<p>Suppose you now want to delete all the rows you recently added to the <code>manufacturers<\/code> table. You might try to run the following <code>DELETE<\/code> statement, using the <code>manufacturer_id<\/code> values for those rows:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">DELETE FROM manufacturers\r\nWHERE manufacturer_id IN (1003, 1004, 1005, 1006);<\/pre>\n<p>When you try to run this statement, MySQL stops statement execution and returns the following error, which indicates you have a foreign key violation:<\/p>\n<p><code>Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`travel`.`airplanes`, CONSTRAINT `fk_manufacturer_id` FOREIGN KEY (`manufacturer_id`) REFERENCES `manufacturers` (`manufacturer_id`))<\/code><\/p>\n<p>MySQL returned this error because you tried to delete a row that was being referenced by the <code>airplanes<\/code> table. As a result, the entire statement failed and no rows were deleted. However, you can ensure that the <code>DELETE<\/code> statement continues to execute even if one of the deletions fails by including the <code>IGNORE<\/code> modifier:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">DELETE IGNORE FROM manufacturers\r\nWHERE manufacturer_id IN (1003, 1004, 1005, 1006);<\/pre>\n<p>Now the statement returns the following message, which shows the number of rows that have been affected and provides a warning:<\/p>\n<p><code>3 row(s) affected, 1 warning(s): 1451 Cannot delete or update a parent row: a foreign key constraint fails (`travel`.`airplanes`, CONSTRAINT `fk_manufacturer_id` FOREIGN KEY (`manufacturer_id`) REFERENCES `manufacturers` (`manufacturer_id`))<\/code><\/p>\n<p>From this message, you can see that three rows have been deleted and that there has been a foreign key violation. If you query the <code>manufacturers<\/code> table, you\u2019ll find that it now contains only three rows, including the one for Airbus. To remove all the Airbus data, you must first delete any referencing records from the <code>airplanes<\/code> table:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">DELETE FROM airplanes\r\nWHERE manufacturer_id = 1003;<\/pre>\n<p>You should then be able to run the following <code>DELETE<\/code> statement to remove the Airbus record from the <code>manufacturers<\/code> table, which will leave you with only two rows in that table:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">DELETE  FROM manufacturers\r\nWHERE manufacturer_id = 1003;<\/pre>\n<p>The <code>IGNORE<\/code> modifier can be useful when you need to schedule a deletion and want the statement execution to continue even if some rows cannot be deleted. This could be especially useful when deleting large sets of data. After the bulk of records have been deleted, you can go back and address any warnings. Be aware, however, that the <code>IGNORE<\/code> modifier works for only certain types of errors.<\/p>\n<h2>Working with the MySQL <code><strong>DELETE<\/strong><\/code> statement<\/h2>\n<p>The <code>DELETE<\/code> statement, along with the <code>SELECT<\/code>, <code>INSERT<\/code>, and <code>UPDATE<\/code> statements, represent four of the most important statements you\u2019ll use when working with MySQL data. However, they\u2019re not the only DML statements. MySQL also supports DML statements such as <code>CALL<\/code>, <code>LOAD<\/code> <code>DATA<\/code>, <code>REPLACE<\/code>, and <code>TABLE<\/code>.<\/p>\n<p>But the four we\u2019ve covered so far in this series are a great place to start for manipulating data, with the <code>DELETE<\/code> statement helping to complete that picture. The statement makes it possible to easily remove data that is incorrect or outdated. In fact, the statement can be almost too easy to use, and you must be careful not to inadvertently delete the wrong data. That said, the <code>DELETE<\/code> statement is extremely useful, and you should be sure that you fully understand how to use it, along with the <code>SELECT<\/code>, <code>INSERT<\/code>, and <code>UPDATE<\/code> statements.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the last few articles in this series, you learned about three important data manipulation language (DML) statements: SELECT, INSERT, and UPDATE. The statements make it possible to retrieve, add, and modify data in a MySQL database. Another DML statement that is just as important is DELETE, which lets you remove one or more rows from a table, including temporary tables. In this article, I focus exclusively on the DELETE statement to help round out our discussion on the core DML statements in MySQL. Overall, the DELETE statement is fairly basic, but one that\u2019s no less necessary to have in your arsenal of DML tools.<\/p>\n<p>&hellip;<\/p>\n","protected":false},"author":221841,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[53,145792],"tags":[],"coauthors":[6779],"class_list":["post-95044","post","type-post","status-publish","format-standard","hentry","category-featured","category-mysql"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/95044","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221841"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=95044"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/95044\/revisions"}],"predecessor-version":[{"id":95107,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/95044\/revisions\/95107"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=95044"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=95044"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=95044"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=95044"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}