我有一个用于 MySQL 的软件升级脚本。
此升级的一部分涉及在表中为预先存在的实体创建行(新版本的软件为新的“父”实体创建了一个额外的关联实体,而旧版本没有,所以我必须手动创建它们) . 子实体 ID 是根据命名约定而不是自动增量代理键组成的。
所以我正在写这个匿名查询:
INSERT INTO CHILD_ENTITIES (CHILD_ID, DESCRIPTION, OBJECT_TYPE)
(SELECT
CONCAT('PRE_', PARENT_ID, '_SUFF') AS CHILD_ID,
CONCAT('DESCRIPTION FOR ', PARENT_NAME) AS DESCRIPTION,
'SYSTEM' AS OBJECT_TYPE
FROM
PARENT_ENTITIES
WHERE
CHILD_ID NOT IN (SELECT
CHILD_ID
FROM
CHILD_ENTITIES));
表结构
CREATE TABLE `CHILD_ENTITIES` (
`CHILD_ID` varchar(50) NOT NULL,
`DESCRIPTION` varchar(200) DEFAULT NULL,
`OBJECT_TYPE` varchar(20) NOT NULL,
PRIMARY KEY (`CHILD_ID`)
)
该查询应该从父表中选择所有父实体,操作行以获得子实体的三个唯一列(注意没有FK约束,这是由于DB设计造成的),然后将它们插入到子实体中。对于每个父母,应该创建一个新的孩子。该WHERE
子句是一个预防性声明,实际上是为了避免重复而编写的,但即使没有,查询仍然应该在正常设置中不会失败WHERE
(因为这些 ID 是通过约定生成的,并且从未手动插入)。
问题是查询MySQL 5.1.69-community
按预期工作正常,但是当运行时5.6.10
(使用 Navicat,如果这很重要)它的行为不同:当父实体存在时不插入记录。
通过几次尝试分析查询,我发现WHERE CHILD ID NOT IN ( SELECT CHILD_ID...
被误解了,指的是子查询的列而不是父选择的列。如果我稍微改变查询
SELECT
CONCAT('PRE_', PARENT_ID, '_SUFF') AS CHILD_ID,
CONCAT('DESCRIPTION FOR ', PARENT_NAME) AS DESCRIPTION,
'SYSTEM' AS OBJECT_TYPE
FROM
PARENT_ENTITIES
WHERE
CHILD_ID NOT IN (SELECT
CHILD_ID AS DUMMY
FROM
CHILD_ENTITIES);
结果:Unknown column 'CHILD_ID' in 'IN/ALL/ANY subquery'
该错误发生在两个版本的 MySQL 上。
那么,我应该如何进行这样的查询以从父 ID 开始填充子实体?