mysql-将匹配多个字段(接近重复项)的所有记录(除1个记录外)标记为已删除
我有一个用于购物车中物品的mysql表。 我需要在“已删除”列中输入时间戳,将同一项目的任何重复项标记为已删除,而不是出于审计跟踪原因实际删除 表order_项的列为:mysql-将匹配多个字段(接近重复项)的所有记录(除1个记录外)标记为已删除,mysql,sql,duplicates,sql-update,inner-join,Mysql,Sql,Duplicates,Sql Update,Inner Join,我有一个用于购物车中物品的mysql表。 我需要在“已删除”列中输入时间戳,将同一项目的任何重复项标记为已删除,而不是出于审计跟踪原因实际删除 表order_项的列为: id (int, primary key) order_id (int) type (enum) item_id* (int) timeslot_id* (int) price_id* (int) created (datetime) deleted (datetime) 我想更新表中除1项之外的所有重复项,这些重复项的值与标
id (int, primary key)
order_id (int)
type (enum)
item_id* (int)
timeslot_id* (int)
price_id* (int)
created (datetime)
deleted (datetime)
我想更新表中除1项之外的所有重复项,这些重复项的值与标记为*的列上的订单的另一行的值相同,以便在删除的列中具有当前日期时间。因此,一次只能购买一种相同的产品
目前,我正在多个阶段中实现这一点,方法是使用GROUPBY和id计数执行select查询,并使用Concat获取以逗号分隔的id列表,然后在单独的查询中更新这些id
SELECT COUNT(id) AS c,
GROUP_CONCAT(DISTINCT id SEPARATOR ",") AS ids
FROM cps_order_item WHERE order_id = "10"
AND deleted = "0000-00-00 00:00:00"
GROUP BY type, item_id, timeslot_id, price_id;
有没有可靠的方法可以在一个查询中完成这一切?我认为您可以通过更新和自连接来实现逻辑:
update order_item oi
inner join (
select order_id, item_id, timeslot_id, price_id, min(id) as id
from order_item
where deleted = '0000-00-00 00:00:00'
group by order_id, item_id, timeslot_id, price_id
) oi1
on oi1.order_id = oi.order_id
and oi1.item_id = oi.item_id
and oi1.timeslot_id = oi.timeslot_id
and oi1.price_id = oi.price_id
and oi1.id <> oi.id
set oi.deleted = now()
where oi.deleted = '0000-00-00 00:00:00'
子查询计算每个值元组的最小id。然后,外部查询为元组上匹配且id不是最小值的行设置删除的列
这会同时处理所有订单。您可以在外部查询的where子句中添加一个过滤器,以仅处理一个订单。如果您愿意,您也可以将聚合函数更改为其他函数,也许您需要maxid而不是minid。我认为您可以通过更新和自连接来实现逻辑:
update order_item oi
inner join (
select order_id, item_id, timeslot_id, price_id, min(id) as id
from order_item
where deleted = '0000-00-00 00:00:00'
group by order_id, item_id, timeslot_id, price_id
) oi1
on oi1.order_id = oi.order_id
and oi1.item_id = oi.item_id
and oi1.timeslot_id = oi.timeslot_id
and oi1.price_id = oi.price_id
and oi1.id <> oi.id
set oi.deleted = now()
where oi.deleted = '0000-00-00 00:00:00'
子查询计算每个值元组的最小id。然后,外部查询为元组上匹配且id不是最小值的行设置删除的列
这会同时处理所有订单。您可以在外部查询的where子句中添加一个过滤器,以仅处理一个订单。如果您愿意,您也可以将聚合函数更改为其他函数,也许您需要maxid而不是minid。注意:此解决方案在MySQL下不起作用。见下面的评论。我希望它能帮助将来使用另一个RDBMS的人
只需删除同一订单中创建日期晚于您考虑的日期的项目。我不太确定MySQL的语法,但它看起来像:
UPDATE order_item o
SET deleted = NOW()
WHERE deleted = '0000-00-00 00:00:00'
AND order_id = 10
AND EXISTS (
SELECT *
FROM order_item
WHERE order_id = o.order_id
AND item_id = o.item_id
AND type = o.type
AND timeslot_id = o.timeslot_id
AND price_id = o.price_id
AND deleted = o.deleted
AND created > o.created
);
我使用了与您给出的查询相同的约束
您可能需要删除AND ORDER=ID行以一次清除所有订单
如果项目id包含这些属性,则可能不需要对price\u id、type和timeslot\u id进行约束。注意:此解决方案在MySQL下不起作用。见下面的评论。我希望它能帮助将来使用另一个RDBMS的人
只需删除同一订单中创建日期晚于您考虑的日期的项目。我不太确定MySQL的语法,但它看起来像:
UPDATE order_item o
SET deleted = NOW()
WHERE deleted = '0000-00-00 00:00:00'
AND order_id = 10
AND EXISTS (
SELECT *
FROM order_item
WHERE order_id = o.order_id
AND item_id = o.item_id
AND type = o.type
AND timeslot_id = o.timeslot_id
AND price_id = o.price_id
AND deleted = o.deleted
AND created > o.created
);
我使用了与您给出的查询相同的约束
您可能需要删除AND ORDER=ID行以一次清除所有订单
假设商品id包含这些属性,那么价格id、类型和时隙id上的约束可能是不必要的。非常感谢@GMB,这非常有用,并且在我记住NULL时非常有用!=mysql比较中的NULL。非常感谢@GMB,这非常有帮助,一旦我记住NULL,它就很有魅力了!=mysql比较中为空。我也喜欢这个答案,但我只想指出,比较创建的记录可能有风险,例如,同时添加了许多记录,这就是为什么我更喜欢其他答案使用MINid。如果您觉得更安全,可以使用id>o.id而不是created>o.created。我很高兴看到您的问题得到了解决:-@FabianPijcke:不幸的是,MySQL不支持在WHERE子句中重新打开目标表,我知道该数据库有这样的限制。。。。您需要将此作为联接查询来编写。我没有意识到这一点,我的缺点是没有尝试运行查询:谢谢您指出这一点!我也喜欢这个答案,但我只想指出,比较创建的记录可能有风险,例如,同时添加了许多记录,这就是为什么我更喜欢其他答案使用MINid。如果您觉得更安全,可以使用id>o.id而不是created>o.created。我很高兴看到您的问题得到了解决:-@FabianPijcke:不幸的是,MySQL不支持在WHERE子句中重新打开目标表,我知道该数据库有这样的限制。。。。您需要将此作为联接查询来编写。我没有意识到这一点,我的缺点是没有尝试运行查询:谢谢您指出这一点!