SQL带INNER JOIN的INSERT语句执行失败 如何正确实现关联插入
错误原因
原有SQL无法执行有三个核心问题:
INSERT ... VALUES语法仅支持直接传入固定值行,不支持在后续拼接JOIN关联逻辑,跨表关联批量插入需要使用INSERT ... SELECT语法结构。- 写入字段列表漏了关联外键
ticket_id,无法存储和tickets表的关联关系。 - 错误地在插入逻辑中关联目标表
ticketChangeSet:执行插入时目标表还没有对应新数据,关联逻辑本身不成立。
JOIN选型说明
你的基础需求不需要使用任何JOIN:只需要从tickets表筛选出id在3-5区间的记录,搭配固定值直接插入即可。
如果需要扩展逻辑(比如避免重复插入已存在关联的记录),选LEFT JOIN,不要用INNER JOIN:
- INNER JOIN只会返回两表匹配成功的行,也就是已经在
ticketChangeSet存在关联记录的ticket,和新增关联记录的需求完全相悖。 - LEFT JOIN会保留左表(tickets)所有符合筛选条件的行,右表(
ticketChangeSet)匹配不到的字段会返回NULL,刚好可以用来过滤还未生成关联记录的ticket。
正确SQL
满足当前需求的最简写法
执行后会为tickets表中id=3、4、5的记录各生成一条关联的ticketChangeSet记录,完全匹配需求:
INSERT INTO ticketChangeSet (Comments, createdBy, createdDateTime, ticket_id) SELECT 'Ticket not resolved', 'system', '2022-07-05 15:59:01', id FROM tickets WHERE id BETWEEN 3 AND 5;
扩展:避免重复插入的写法
如果需要防止同一个ticket重复生成changset记录,可以用LEFT JOIN做过滤:
INSERT INTO ticketChangeSet (Comments, createdBy, createdDateTime, ticket_id) SELECT 'Ticket not resolved', 'system', '2022-07-05 15:59:01', t.id FROM tickets t LEFT JOIN ticketChangeSet tcs ON t.id = tcs.ticket_id WHERE t.id BETWEEN 3 AND 5 AND tcs.id IS NULL;
执行效果
执行完成后ticketChangeSet表会新增3条记录,结果如下:
| id | comments | createdBy | createdDateTime | ticket_id |
|---|---|---|---|---|
| 1 | Ticket not resolved | system | 2022-07-05 15:59:01 | 2 |
| 2 | Ticket not resolved | system | 2022-07-05 15:59:01 | 3 |
| 3 | Ticket not resolved | system | 2022-07-05 15:59:01 | 4 |
| 4 | Ticket not resolved | system | 2022-07-05 15:59:01 | 5 |
内容的提问来源于stack exchange,提问作者Darlisa Cardiff
相关产品推荐
相关产品推荐

