我有这个问题,现在已经杀了我几天了。
所以我们有一张所有已处理订单的表格。 我们为所有订单提供了一张表。
我们需要有效地交叉引用新表中的订单,这些订单会根据主表中已完全完成的订单不断更新,以便我们不会多次完成相同的订单。
在我们收到一批新订单后,这是我当前运行的查询,试图将其与已完成订单表交叉引用:
$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”中已存在具有相同order
,name
和jurisdiction
的行“表。
这是处理此类查询的正确方法吗?
答案 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)
不,您的查询将删除任何记录中包含相同order
,name
和jurisdiction
的记录,即使这些记录彼此不同也是如此。换句话说,如果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;