Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mysql-将匹配多个字段(接近重复项)的所有记录(除1个记录外)标记为已删除_Mysql_Sql_Duplicates_Sql Update_Inner Join - Fatal编程技术网

mysql-将匹配多个字段(接近重复项)的所有记录(除1个记录外)标记为已删除

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项之外的所有重复项,这些重复项的值与标

我有一个用于购物车中物品的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项之外的所有重复项,这些重复项的值与标记为*的列上的订单的另一行的值相同,以便在删除的列中具有当前日期时间。因此,一次只能购买一种相同的产品

目前,我正在多个阶段中实现这一点,方法是使用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子句中重新打开目标表,我知道该数据库有这样的限制。。。。您需要将此作为联接查询来编写。我没有意识到这一点,我的缺点是没有尝试运行查询:谢谢您指出这一点!