MySQL 使用 select 和 join 插入 post_meta - 我做错了啥?

Posted

技术标签:

【中文标题】MySQL 使用 select 和 join 插入 post_meta - 我做错了啥?【英文标题】:MySQL Insert into post_meta with select and join - what am I doing wrong?MySQL 使用 select 和 join 插入 post_meta - 我做错了什么? 【发布时间】:2018-11-04 06:32:24 【问题描述】:

所以,我正在尝试运行 SQL 操作:

INSERT INTO wp4t_postmeta (post_id, meta_key, meta_value)
SELECT a.post_id, '_attached_image', b.ID
FROM wp4t_postmeta a 
INNER JOIN wp4t_posts b ON a.meta_value WHERE a.meta_key="_content_field_42" 
= b.guid

基本上,我需要使用帖子 ID、元键(attached_image)和元值更新 wp4t_postmeta 表。

当 wp4t_postmeta 中 meta_key _content_field_42 的 meta_value 与 wp4t_posts 的 guid 匹配时,我需要来自 wp4t_posts ID 的 meta_value。

一开始我每次尝试运行它时 tmp 目录中的大小都用完了,所以我添加了一个限制来测试它:

INSERT INTO wp4t_postmeta (post_id, meta_key, meta_value)
SELECT a.post_id, '_attached_image', b.ID
FROM wp4t_postmeta a 
INNER JOIN wp4t_posts b ON a.meta_value WHERE a.meta_key="_content_field_42" 
= b.guid LIMIT 10;

现在我收到错误“#1062 - 键 'PRIMARY' 的重复条目 '0'”

我知道这是 wp4t_postmeta 中的 meta_id 自动递增表,但我想如果我不包含它,它会自动递增吗?

我在这里做错了什么?

另外,有没有更好的方法来编写这个查询?

更新....取得进展:

INSERT INTO wp4t_postmeta (post_id, meta_key, meta_value)
SELECT postmeta.post_id, '_attached_image', posts.ID
FROM wp4t_postmeta AS postmeta 
INNER JOIN wp4t_posts AS posts ON postmeta.meta_value = posts.guid  
WHERE postmeta.meta_key="_content_field_42"
AND posts.post_type="attachment"

编辑....仍在发展:

INSERT INTO wp4t_postmeta (post_id, meta_key, meta_value)
SELECT postmeta.post_id, '_attached_image', posts.ID 
FROM wp4t_postmeta AS postmeta 
INNER JOIN wp4t_posts AS posts ON postmeta.meta_value = posts.guid 
AND postmeta.meta_key = '_content_field_42' 
WHERE posts.post_type="attachment"

【问题讨论】:

见meta.***.com/questions/333952/… 感谢@str的帮助 @LawrenceBlack 确保您没有注册任何触发器 @LawrenceBlack,您应该就 Rick 的回答提供反馈 @Omkaar.K - Stack Overfart 从您的代表中扣除赏金。而且,如果你不奖励它,他们甚至不会把它还给你。可悲的是,除我之外的另一个答案是完全不正确的。我回答了,但我不能给自己赏金。赢一些,输一些。 【参考方案1】:

我要花点时间来回答这个问题。

我的查询是正确的。

我根本没有打开 AutoIncrement,因为我删除了无效的 ID 0。

编辑:最终正确查询

-----------------------------------------------------------------
INSERT INTO wp4t_postmeta (post_id, meta_key, meta_value)
SELECT postmeta.post_id, '_attached_image', posts.ID 
FROM wp4t_postmeta AS postmeta 
INNER JOIN wp4t_posts AS posts ON postmeta.meta_value = posts.guid 
WHERE postmeta.meta_key = '_content_field_42' 
AND posts.post_type="attachment"
-----------------------------------------------------------------

在 wp_postmeta 中具有超过 1MM 表的 VPS 服务器上工作 - 花了一些时间,但它运行了。

【讨论】:

这解释了你做错的一个【参考方案2】:

只要a.meta_value 不为空,ON a.meta_value 就为“真”。那可能不是你想要的。也许是这样:

ON b.id = a.post_id

如果这还不够,让我们看看ab 的一些相关行。

进一步说明:当ON 子句始终为“真”时,您正在构建一个临时表,它是ab所有 组合。如果每个都有 10K 行,那将是一个有 100M 行的临时表。这可能会溢出 tmp 目录中的空间。

但是,如果您超过了这一点,您可能会使用相同的 a.post_id 达到 10K 行

但即使这样也不能解释一切。如果我没记错的话,post_id 是一个AUTO_INCREMENT,通常不包含0。获得0 的唯一可能方法是显式插入0

但这就是你正在做的事情。

好的,我无法推断出原始 0 的来源,但这很可能是另一个问题的线索。

【讨论】:

@LawrenceBlack -- 是的,就是我,兄弟! 可能的奖励(不确定是否适用于此处):wp_postmeta 目前定义的效率相当低。我的改进笔记:mysql.rjweb.org/doc.php/…

以上是关于MySQL 使用 select 和 join 插入 post_meta - 我做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 MYSQL 中执行 LEFT OUTER JOIN 时插入零而不是 NULL

mysql中insert与select的嵌套使用解决组合字段插入问题

生产环境为啥尽量不用join

MySQL的JOIN:用法

MySQL的JOIN

MySQL 嵌入式 SELECT 与 JOIN