【问题标题】:Deleting table entries based on criteria in another table根据另一个表中的条件删除表条目
【发布时间】:2020-12-26 21:38:07
【问题描述】:

我们希望能够根据在另一个表中设置的删除条件从 MySQL 表中删除条目。让我用一个例子来解释。
我有两个表定义如下:

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 有数据,del_criteria_tbl 有从@9​​87654324@ 删除条目的条件。

我按如下方式填充表格:

INSERT INTO base_tbl(f1, f2) VALUES ('ABC', '123C57'),
('ABC', '532B49'), ('DEF', '397F45'),
('DEF', '684G65'), ('GHI', '793A86'),
('GHI', '541H32');  

INSERT INTO del_criteria_tbl(f3, f4) VALUES ('ABC', '532B49'),
('ABC', '813E89'), ('DEF', '397F45'),
('GHI', '541H32');

显然:

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 |
+----+------+--------+

我想定义一个简洁高效的SQL操作,执行如下伪SQL逻辑:

DELETE FROM base_tbl WHERE base_tbl.f1 = del_criteria_tbl.f3 AND base_tbl.f2 = del_criteria_tbl.f4

操作执行后,SELECT * FROM base_tbl应该yield:

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

【问题讨论】:

    标签: mysql sql mariadb subquery sql-delete


    【解决方案1】:

    一个简单的方法是IN:

    DELETE b FROM base_tbl b
        WHERE (b.f1, b.f2) IN (SELECT dc.f3, dc.f4
                               FROM del_criteria_tbl dc
                              );
    

    使用(f1, f2) 上的索引,您可能会发现JOIN 具有更好的性能:

    DELETE b
        FROM base_tbl b JOIN
             del_criteria_tbl dc
             ON b.f1 = dc.f3 AND b.f2 = c.f4;
    

    【讨论】:

      【解决方案2】:

      我会推荐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
      )
      

      这似乎是表达您要求的最自然的方式。在大型数据集上,exists 通常比in 具有更好的扩展性。为了提高性能,您需要在del_criteria_tbl(f1, f2) 上建立索引。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-17
        • 2020-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-17
        • 1970-01-01
        相关资源
        最近更新 更多