mysql - 无法在 FROM 子句中指定要更新的目标表 t4

标签 mysql sql

我正在尝试更新我的表格:

UPDATE offers t1
SET t1.deleted_at = NOW()
WHERE t1.id 
    NOT IN
    (
        SELECT f.id
        FROM (
        SELECT ean, MIN(net_price) as minprice
        FROM offers group BY ean
        ) 
        as x inner join offers as f on f.ean = x.ean and f.net_price = x.minprice
    );

谁能帮我解决这个问题? 我意识到我需要通过左连接来解决问题,但不明白如何在我的案例中应用它。谢谢。

这里是创建表:

CREATE TABLE `offers` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `net_price` decimal(10,2) unsigned DEFAULT NULL,
  `retail_price` decimal(10,2) unsigned DEFAULT NULL,
  `supplier_id` bigint unsigned DEFAULT NULL,
  `manufacturer_id` bigint unsigned DEFAULT NULL,
  `stock` int DEFAULT NULL,
  `ean` varchar(14) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `mnn_id` bigint unsigned DEFAULT NULL,
  `source_id` bigint unsigned NOT NULL,
  `nds` smallint unsigned DEFAULT NULL,
  `to_export` tinyint(1) DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `offers_supplier_id_foreign` (`supplier_id`),
  KEY `offers_manufacturer_id_foreign` (`manufacturer_id`),
  KEY `offers_mnn_id_foreign` (`mnn_id`),
  KEY `offers_source_id_foreign` (`source_id`),
  CONSTRAINT `offers_manufacturer_id_foreign` FOREIGN KEY (`manufacturer_id`) REFERENCES `manufacturers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `offers_mnn_id_foreign` FOREIGN KEY (`mnn_id`) REFERENCES `mnns` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `offers_source_id_foreign` FOREIGN KEY (`source_id`) REFERENCES `sources` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `offers_supplier_id_foreign` FOREIGN KEY (`supplier_id`) REFERENCES `suppliers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=25762 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

最佳答案

你得到的错误是

You can't specify target table 't1' for update in FROM clause

这是MySQL特有的问题。您不能在子查询中直接访问更新的表,您需要一个子子查询:-)

替换

inner join offers as f

通过

inner join (select * from offers) as f

因此使查询正常工作。

顺便说一句,您不需要连接。你可以只写

UPDATE offers
SET deleted_at = NOW()
WHERE (ean, net_price) NOT IN
(
  SELECT ean, MIN(net_price)
  FROM (select * from offers) o
  GROUP BY ean
);

另一种写法(更新同一 EAN 存在较低价格的所有行):

UPDATE offers t1
SET t1.deleted_at = NOW()
WHERE EXISTS
(
  SELECT NULL
  FROM (SELECT * FROM offers) t2
  WHERE t2.ean = t1.ean
  AND t2.net_price < t1.net_price
);

演示:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=bfa6d74a72d40fa445ea5fa9f95803d1

顺便说一下:您可能希望将条件 deleted_at IS NULL 添加到您的更新语句中,以便不更新已逻辑删除的行(如果存在此类行)。

关于mysql - 无法在 FROM 子句中指定要更新的目标表 t4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68342078/

相关文章:

mysql - 如何在 mysql 上添加条件以根据列值获取不同表上的值

mysql - 与 MySQL 中的 NOW() 比较日期

php - PDOStatement::rowCount 结果在 PDO::commit 之后使用?

mysql - 连接/合并两个表,即兴/组成 "missing"条目

mysql - 将数据插入有条件的表中的每条记录中,但自动填充它......我会尽力解释 :-)

java - 如何解决java.sql.SQLNonTransientConnectionException : Could not read resultset: Connection reset?

mysql - 使用 TIdHTTPServer 时如何防止 "MySql has gone away"

sql - 其类型不能用作索引中的键列

sql - Rails 通过 JSON 属性搜索

sql - 雪花-sql : case when min vs first_value windows function