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

cs7cruho  于 2021-06-18  发布在  Mysql
关注(0)|答案(3)|浏览(334)

我有下面的工作选择声明。

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       |

我想更新一下 option_valuetblfoo 相关数据来自 contenttblbar . 不幸的是, tblbar 可能有多个条目 refid 具有相同的值。这就是为什么需要 LIMIT 1 (或 GROUP BY t,id 或者 DISTINCT )使用子查询。
我发现,当我使用 LIMIT 1 而不是子查询 SELECT DISTINCT 或与…结合 GROUP BY t1.id . 所以在执行时间优化之后,我最终得到了上面的select语句。
源表还有一个catch,应该更新它。 option_value 是一个实际字段,也存在于源表中(但带有 NULL 值)。
我在尝试将上面的优化select语句转换为update语句时遇到的问题主要是我无法访问 t1.id 从子查询内部。
如何将select语句转换为update语句而不丢失性能优化?

cetgtptt

cetgtptt1#

只需将updatejoin与子查询一起使用,子查询在 tblbar :

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

lf3rwulv2#

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

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

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

kxeu7u2r

kxeu7u2r3#

您的相关子查询可以通过避免 Left Join 在两张table之间。相反,您可以直接获得 content 第二个表中的值。
对于更新,您可以使用 select 作为派生表进行查询,并将其联接到源表:

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;

相关问题