【发布时间】:2023-03-31 02:08:01
【问题描述】:
试图让 UPDATE 与 MySQL 中的 CTE 一起工作,我快疯了。
这是sa_general_journal 的简化架构:
CREATE TABLE `sa_general_journal` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Transaction_ID` int(10) unsigned DEFAULT NULL COMMENT 'NULL if not split, same as ID for split records',
`Date` timestamp NOT NULL DEFAULT current_timestamp(),
…
`Statement_s` int(10) unsigned DEFAULT NULL,
…
`Name` varchar(255) DEFAULT NULL,
…
PRIMARY KEY (`ID`),
…
) ENGINE=InnoDB AUTO_INCREMENT=25929 DEFAULT CHARSET=utf8;
某些记录是“拆分的”,例如,信用卡对帐单金额可能包含拆分的销售税金额。在这种情况下,拆分记录的两个部分在 Transaction_ID 字段中具有相同的 ID。
批量导入记录时,不能引用last_insert_ID填写Transaction_ID字段,所以需要在后面清理这些。
这是我第一次天真的尝试,它说我在UPDATE 附近有一个错误。嗯嗯。
WITH cte AS (
SELECT
ID,
MIN(ID) OVER(PARTITION BY `Date`, `Name`, Statement_s) AS Trans,
Transaction_ID
FROM sa_general_journal
WHERE Transaction_ID = 0)
UPDATE cte
SET Transaction_ID = Trans
CTE 本身似乎有效,因为我可以使用 SELECT * FROM cte 跟踪它并得到我所期望的。
所以我开始搜索 StackOverflow,发现 CTE 不可更新,但您需要将它们加入到要更新的内容中。 “没问题!”我想,当我编写代码时:
WITH cte AS (
SELECT
ID,
MIN(ID) OVER(PARTITION BY `Date`, `Name`, Statement_s) AS Trans,
Transaction_ID
FROM sa_general_journal
WHERE Transaction_ID = 0)
UPDATE sa_general_journal gj, cte
SET gj.Transaction_ID = cte.Trans
WHERE gj.ID = cte.ID
没有快乐。同样的错误信息。
我的理解是,在 MySQL 中,您不需要列列表,但我也尝试使用列列表 (a, b, c),在 UPDATE 语句中引用了正确的列,但它仍然说我UPDATE附近有问题。
在互联网上使用UPDATE 和WITH 的例子非常少!我找到了一个,from Percona,这是我在上面尝试创建的,然后找到了另一个非常相似的示例 from MySQL itself。
提前感谢您提供的任何帮助!
【问题讨论】:
-
请在更新前后向您的问题添加示例数据。这将帮助您更快地得到答案。
-
感谢您的建议。不幸的是,我不再有任何“之前”数据,这要感谢@Akina,他在下面提供了解决方案。
标签: mysql sql-update mariadb common-table-expression