基于多个不同列的MYSQL删除

时间:2016-12-16 18:57:16

标签: php mysql

我有这个问题,现在已经杀了我几天了。

所以我们有一张所有已处理订单的表格。 我们为所有订单提供了一张表。

我们需要有效地交叉引用新表中的订单,这些订单会根据主表中已完全完成的订单不断更新,以便我们不会多次完成相同的订单。

在我们收到一批新订单后,这是我当前运行的查询,试图将其与已完成订单表交叉引用:

$sql = "DELETE
FROM
    `orders_new`
WHERE
    `order` IN (
        SELECT DISTINCT
            `order`
        FROM
            `orders_all`
    )
AND `name` IN (
    SELECT DISTINCT
        `name`
    FROM
        `orders_all`
)
AND `jurisdiction` IN (
    SELECT DISTINCT
        `jurisdiction`
    FROM
        `orders_all`
)";

正如您可能知道的那样,我想删除“orders_new”表中的行,其中“orders_all”中已存在具有相同ordernamejurisdiction的行“表。

这是处理此类查询的正确方法吗?

3 个答案:

答案 0 :(得分:1)

嗯,正确的方法取决于很多事情。 但首先,我不喜欢你的分为两个表。在这种情况下,我将引入一个列标识状态,该woul引用具有可能状态的表。那些将是“新的”,“在进行中”,“完成”。这样,您只需将一个订单存储为一个记录。 但您的查询迁移没问题,但您应该检查性能。 看看:https://sqlperformance.com/2012/12/t-sql-queries/left-anti-semi-join 不完全是你的情况,但非常相似。

另一件事:为什么使用DISTINCT。这意味着“订单”不是唯一的标识符。

根据您的编辑,您可以使用复合键“order”,“name”,“辖区”来标识订单。这真的是关键,整个关键,除了关键,所以帮助你Codd。如果没有,您可以删除一堆记录。但即使这样,您的查询也会删除所有订单,其名称和管辖权可以按照表格顺序在不同的记录中找到。所以你的查询是假的。

说,您的查询的变体可能是

DELETE order_new
FROM
    order_new
    INNER JOIN
    order_all ON order_all.order = order_new.order 
                    AND order_all.name = order_new.name
                    AND order_all.jurisdiction = order_new.jurisdiction

但是,真正的问题是你的ER模型。

答案 1 :(得分:0)

您应该将其转换为{/ 1}}结构,如

DELETE - JOIN

答案 2 :(得分:0)

不,您的查询将删除任何记录中包含相同ordernamejurisdiction的记录,即使这些记录彼此不同也是如此。换句话说,如果orders_new中的一行具有相同的order_all,另一行具有相同的order,并且第三行具有相同的name,则jurisdiction中的行将被删除相同的DELETE FROM `orders_new` WHERE (`order`, `name`, jurisdiction`) IN ( SELECT `order`, `name`, `jurisdiction` FROM `orders_all` ) 。你非常有可能删除超出你想要的方式。相反,这更合适:

DELETE FROM `orders_new` 
WHERE EXISTS (
  SELECT 1
  FROM `orders_all` AS oa
  WHERE oa.`order` = `orders_new`.`order`
    AND oa.`name` = `orders_new`.`name`
    AND oa.`jurisdiction` = `orders_new`.`jurisdiction`
)

或者

@Autowired
private ParameterRepository repo;