从一个查询中的两个表中删除行

时间:2009-08-27 09:14:09

标签: mysql cascade

我有两个表:orders和orders_items。两者都共享字段orderID。

我想删除orderID = 500的两个表中的所有行,但我只需要在一个查询中执行此操作。这可能吗?

6 个答案:

答案 0 :(得分:10)

当然你可以这样做:

DELETE FROM `table1`, `table2` WHERE `orderId` = 500

请参阅http://dev.mysql.com/doc/refman/5.0/en/delete.html

[编辑:

这是一个完整的伎俩:

DELETE FROM `orders`, `orders_items` 
  USING `orders` 
  INNER JOIN `orders_items` ON `orders`.`orderId` = `orders_items`.`orderId` 
  WHERE `orders`.`orderId`= 500

如果orderId是varchar,则将语句更改为= '500'

答案 1 :(得分:8)

您可以使用 ON DELETE CASCADE 定义表格。如果这样做,您只需要在订单表上删除。使用 order_id 作为启用该选项的外键的其他表中的条目将自动删除。

此示例取自MySQL manual

CREATE TABLE parent(
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=INNODB;

CREATE TABLE child(
    id INT, parent_id INT,
    INDEX par_ind (parent_id),
    FOREIGN KEY (parent_id) REFERENCES parent(id) ON DELETE CASCADE
) ENGINE=INNODB;

请注意,引擎是InnoDB。

答案 2 :(得分:3)

这取决于您的数据库引擎,但基本上您需要的声音就像您希望一个表使用带有FOREIGN KEY选项的ON DELETE CASCADE引用另一个表,然后从父表中删除将自动删除相应的行来自附属表。

答案 3 :(得分:2)

如果您正在使用MySQL / PgSQL,那么这是一个简单的解决方案......

DELETE t1, t2 FROM table1 AS t1 
LEFT JOIN table2 AS t2 USING( orderID ) 
WHERE t1.orderID = 500;

保证像魅力一样工作!

请确保将 table1 table2 替换为您的相应表格名称。

我在自定义设计的CMS中使用了大量此查询 - 无论何时我想避免两个不同的原子查询。这与级联删除一样好,并且可以将查询扩展为跨越任意数量的表。

这是另一个涉及3个表的例子:

DELETE t1, t2, t3 FROM table1 AS t1 
LEFT JOIN table2 AS t2 USING( orderID ) 
LEFT JOIN table3 AS t3 USING( orderID ) 
WHERE t1.orderID = 500;

干杯, 米^ E

答案 4 :(得分:2)

如果您正在使用InnoDB(或支持它们的存储引擎),您可以使用FOREIGN KEY constraints删除对应的行。如果您不介意外键对性能的轻微影响,这是最简单/最安全的方法之一。但请注意,由于约束而删除的行不会触发触发器。

或者,您可以使用触发器。它们适用于任何存储引擎,它们通常很容易编写。我喜欢它们,但如果你一次删除大量行(几百或几千行),它们就不是很有效。

CREATE TRIGGER ad_orders AFTER DELETE ON orders
FOR EACH ROW DELETE FROM orders_items WHERE orderID = OLD.orderID;

最后,正如上一个答案中所建议的那样,您可以使用多表DELETE:

DELETE o, oi
FROM orders o
LEFT JOIN orders_items oi USING (orderID)
WHERE o.orderID = 500;

答案 5 :(得分:1)

您可以使用存储的函数并调用它吗?

然后在您的存储函数中,您将同时拥有两个DELETE查询。然后,当调用存储的函数时,它将作为事务运行,您可以返回任何您喜欢的函数。