We want to be able to delete entries from a MySQL table, based on deletion criteria set in another table. Let me explain with an example.
I have two tables defined as follows:
CREATE TABLE base_tbl
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
f1 VARCHAR(8),
f2 VARCHAR(8),
PRIMARY KEY (id)
);
CREATE TABLE del_criteria_tbl
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
f3 VARCHAR(8),
f4 VARCHAR(8),
PRIMARY KEY (id)
);
base_tbl
has the data and del_criteria_tbl
has the criteria for deleting entries from base_tbl
.
I populate the tables as follows:
INSERT INTO base_tbl(f1, f2) VALUES ('ABC', '123C57'),
('ABC', '532B49'), ('DEF', '397F45'),
('DEF', '684G65'), ('GHI', '793A86'),
('GHI', '541H32');
and
INSERT INTO del_criteria_tbl(f3, f4) VALUES ('ABC', '532B49'),
('ABC', '813E89'), ('DEF', '397F45'),
('GHI', '541H32');
Obviously:
mysql>SELECT * FROM base_tbl;
+----+------+--------+
| id | f1 | f2 |
+----+------+--------+
| 1 | ABC | 123C57 |
| 2 | ABC | 532B49 |
| 3 | DEF | 397F45 |
| 4 | DEF | 684G65 |
| 5 | GHI | 793A86 |
| 6 | GHI | 541H32 |
+----+------+--------+
mysql>SELECT * FROM del_criteria_tbl;
+----+------+--------+
| id | f3 | f4 |
+----+------+--------+
| 1 | ABC | 532B49 |
| 2 | ABC | 813E89 |
| 3 | DEF | 397F45 |
| 4 | GHI | 541H32 |
+----+------+--------+
I would like to define a succinct and efficient SQL operation that executes the following pseudo-SQL logic:
DELETE FROM base_tbl WHERE base_tbl.f1 = del_criteria_tbl.f3 AND base_tbl.f2 = del_criteria_tbl.f4
After the operation is executed, SELECT * FROM base_tbl
should yield:
+----+------+--------+
| id | f1 | f2 |
+----+------+--------+
| 1 | ABC | 123C57 |
| 4 | DEF | 684G65 |
| 5 | GHI | 793A86 |
+----+------+--------+
A simple method is IN
:
DELETE b FROM base_tbl b
WHERE (b.f1, b.f2) IN (SELECT dc.f3, dc.f4
FROM del_criteria_tbl dc
);
With indexes on (f1, f2)
, you might find a JOIN
has better performance:
DELETE b
FROM base_tbl b JOIN
del_criteria_tbl dc
ON b.f1 = dc.f3 AND b.f2 = c.f4;
I would recommend exists
:
delete b
from base_tbl b
where exists (
select 1
from del_criteria_tbl dc
where dc.f1 = b.f1 and dc.f2 = b.f2
)
This seems like the most natural way to phrase what you ask for. exists
usually scales better than in
over large datasets. For performance, you want an index on del_criteria_tbl(f1, f2)
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.