如何将带有子查询的MySQL select语句转换为update语句?

如何将带有子查询的MySQL select语句转换为update语句?,mysql,sql,sql-update,subquery,Mysql,Sql,Sql Update,Subquery,我有下面的工作select语句 SELECT t1.id, t1.option_key, ( SELECT t3.content AS option_value FROM tblfoo t2 LEFT OUTER JOIN tblbar t3 ON( t3.refid = t2.id ) WHERE t2.id = t1.id LIMIT 1 ) AS option_value FROM tblfoo t1 表结构如下所示: | tbl

我有下面的工作select语句

SELECT t1.id, t1.option_key, ( 
    SELECT
        t3.content AS option_value
    FROM tblfoo t2
    LEFT OUTER JOIN tblbar t3 ON( t3.refid = t2.id )
    WHERE t2.id = t1.id
    LIMIT 1
) AS option_value
FROM tblfoo t1
表结构如下所示:

| tblfoo                         |
+----+------------+--------------+
| id | option_key | option_value |
+----+------------+--------------+
|  1 | foo        | NULL         |
|  2 | bar        | NULL         |
|  3 | baz        | NULL         |


| tblbar               |
+----+-----------------+
| id | refid | content |
+----+-----------------+
|  1 |     1 | value1  |
|  1 |     2 | value2  |
|  1 |     3 | value3  |
update语句的结果应该是:

| tblfoo                         |
+----+------------+--------------+
| id | option_key | option_value |
+----+------------+--------------+
|  1 | foo        | value1       |
|  2 | bar        | value2       |
|  3 | baz        | value3       |
我想用
tblfoo
更新
option\u值,使用
tblbar
中的
content
中的相关数据。不幸的是,
tblbar
可能有多个具有相同值的
refid
条目。这就是为什么子查询需要
LIMIT 1
(或
groupby t,id
DISTINCT

我发现,当我使用
LIMIT 1
进行子查询时,查询速度明显加快,而不是使用
SELECT DISTINCT
进行子查询,或者使用
groupby t1.id
进行连接。所以在执行时间优化之后,我使用上面的select语句结束了

源表还有一个catch,应该更新它<代码>选项_值
是一个实际字段,它也存在于源表中(但具有
NULL
值)

我在尝试将上面的优化select语句转换为update语句时遇到的问题主要是我无法从子查询内部访问
t1.id


如何在不丢失性能优化的情况下将select语句转换为update语句?

可以通过避免两个表之间的
左连接来进一步优化相关子查询。相反,您可以直接从第二个表中获取
内容

要进行更新,您可以使用
选择
查询作为派生表,并将其连接到源表:

UPDATE tblfoo AS tfoo 
JOIN (
      SELECT t1.id, 
             (SELECT t3.content AS option_value
              FROM tblbar t3
              WHERE t3.refid = t1.id
              LIMIT 1
             ) AS option_value
      FROM tblfoo t1
     ) AS dt ON dt.id = tfoo.id 
SET tfoo.option_value = dt.option_value;

通过避免两个表之间的
左联接
,可以进一步优化相关子查询。相反,您可以直接从第二个表中获取
内容

要进行更新,您可以使用
选择
查询作为派生表,并将其连接到源表:

UPDATE tblfoo AS tfoo 
JOIN (
      SELECT t1.id, 
             (SELECT t3.content AS option_value
              FROM tblbar t3
              WHERE t3.refid = t1.id
              LIMIT 1
             ) AS option_value
      FROM tblfoo t1
     ) AS dt ON dt.id = tfoo.id 
SET tfoo.option_value = dt.option_value;

只需将更新联接与在
tblbar
中查找不同值的子查询一起使用即可:

UPDATE tblfoo f
INNER JOIN
(
    SELECT DISTINCT refid, content
    FROM tblbar
) b
    ON f.id = b.refid
SET f.option_value = b.content;

只需将更新联接与在
tblbar
中查找不同值的子查询一起使用即可:

UPDATE tblfoo f
INNER JOIN
(
    SELECT DISTINCT refid, content
    FROM tblbar
) b
    ON f.id = b.refid
SET f.option_value = b.content;

如果要更新所有行,则最有效的方法可能是:

UPDATE tblfoo f
    SET f.option_value = (SELECT b.content FROM tblbar WHERE f.id = b.refid LIMIT 1);

特别是,这可以利用
tblbar(refid,content)

上的索引,如果要更新所有行,那么最有效的方法可能是:

UPDATE tblfoo f
    SET f.option_value = (SELECT b.content FROM tblbar WHERE f.id = b.refid LIMIT 1);


特别是,这可以利用
tblbar(refid,content)

上的索引来更新哪些表/列和哪些数据?在子查询中,为什么要联接表2和表3;我相信您可以直接使用Table3来显示您正在尝试的代码update@TimBiegeleisen我已经用表结构和更清晰的说明编辑了我的问题,哪些字段应该更新。如果有重复的值,您想使用哪个值?哪些表/列正在用哪些数据更新?在子查询中,为什么加入表2和表3;我相信您可以直接使用Table3来显示您正在尝试的代码update@TimBiegeleisen我已经用表格结构和更清晰的说明编辑了我的问题,哪些字段应该更新。如果有重复的值,您想使用哪一个?谢谢,您的SQL可以工作,但有一个改动:它是
设置f.content=b.option\u值。你能更新你的答案吗?那么我可以接受了:)@burnersk事实上,从你给我们看的表格来看,我的答案似乎是正确的。如果没有,请更新您的问题。对不起,您是正确的。我必须匿名的公司限制让我快死了。谢谢你,你的SQL有效,但有一个改动:它是
SET f.content=b.option\u value。你能更新你的答案吗?那么我可以接受了:)@burnersk事实上,从你给我们看的表格来看,我的答案似乎是正确的。如果没有,请更新您的问题。对不起,您是正确的。我必须匿名的公司限制让我快死了。你的更新声明有效。然而,@TimBiegeleisen的版本运行速度更快(1分钟比10分钟)@burnersk-yeah-Tim进一步优化。我没有整体优化您的原始查询;只有子查询部分。update语句可以工作。然而,@TimBiegeleisen的版本运行速度更快(1分钟比10分钟)@burnersk-yeah-Tim进一步优化。我没有整体优化您的原始查询;只是子查询部分。