简体   繁体   English

根据另一个表中的条件删除表条目

[英]Deleting table entries based on criteria in another table

We want to be able to delete entries from a MySQL table, based on deletion criteria set in another table.我们希望能够根据在另一个表中设置的删除标准从 MySQL 表中删除条目。 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 . base_tbl具有数据,而del_criteria_tbl具有从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:我想定义一个简洁高效的 SQL 操作,执行如下伪 SQL 逻辑:

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:操作执行后, SELECT * FROM base_tbl应该产生:

+----+------+--------+
| id | f1   | f2     |
+----+------+--------+
|  1 | ABC  | 123C57 |
|  4 | DEF  | 684G65 |
|  5 | GHI  | 793A86 |
+----+------+--------+

A simple method is IN :一个简单的方法是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:使用(f1, f2)上的索引,您可能会发现JOIN具有更好的性能:

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 :我会推荐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. exists通常比in大型数据集中更好地扩展。 For performance, you want an index on del_criteria_tbl(f1, f2) .为了提高性能,您需要del_criteria_tbl(f1, f2)上的索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM