我有两个表:orders 和 orders_items。两者共享字段 orderID。
我想从两个表中删除 orderID=500 的所有行,但我只需要在一个查询中执行此操作。这可能吗?
你当然可以这样做:
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'
.
您可以使用ON DELETE CASCADE定义表。如果你这样做,你只需要在订单表上删除。使用order_id作为外键并启用该选项的其他表中的条目将被自动删除。
此示例取自MySQL 手册:
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。
这取决于您的数据库引擎,但基本上您需要的听起来像是您希望一个表使用FOREIGN KEY
withON DELETE CASCADE
选项引用另一个表,然后从父表中删除将自动从相关表中删除相应的行。
如果您使用的是 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;
干杯,m^e
如果您使用 InnoDB(或支持它们的存储引擎),您可以使用FOREIGN KEY 约束来删除相应的行。如果您不介意外键对性能的轻微影响,这是最简单/最安全的方法之一。但是请注意,由于约束而删除的行不会触发触发器。
或者,您可以使用触发器。它们适用于任何存储引擎,并且通常很容易编写。我喜欢它们,但是如果您一次删除大量行(数百或数千行),它们的性能就不是很好。
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;
你可以使用存储函数并调用它吗?
然后在您存储的函数中,您将有两个 DELETE 查询。然后,当存储的函数被调用时,它将作为一个事务运行,你可以让它返回任何你喜欢的东西。