【问题标题】:Combine multiple select with update结合多选和更新
【发布时间】:2023-04-08 15:21:01
【问题描述】:

我有一个查询拖累了我的应用程序。必须有一种方法可以通过选择加入更新来改善这一点。任何帮助表示赞赏。这是非常慢的查询:

Select t1.id, t2.tracker from Table1 t1, Table2 t2 where t1.id=t2.id and t2.tracker is not null

上面返回一个我可以处理的行集。对于返回的每一行,我在 第三个表,看看是否只有 1 行存在:

select tracker from Table3 where tracker="from above query". 

如果跟踪器在表 3 中的计数为 1 行,则我对表 1 执行更新。

Update Table 1, set some field where id=t1.id

我该如何组合呢?列出的答案很棒,但我想这个问题还不够清楚。因此,我编辑了这个问题。

表 1 返回要更新的 ID 的可能列表。 表 2 返回我需要搜索表 3 的跟踪器。 表 3 告诉我跟踪器是否只存在一次,所以我可以使用它返回表 1 并 更新它。

【问题讨论】:

    标签: mysql join sql-update subquery


    【解决方案1】:

    通过使用HAVING 子句和额外的LEFT JOIN,您可以将前两个查询组合成一个查询,仅返回tracker,仅针对在Table3 中有一条记录且表达式为HAVING COUNT(t3.tracker) = 1 的那些查询

    SELECT 部分看起来像:

    SELECT
      t1.id,
      t2.tracker
    FROM 
      -- Your original comma-separated FROM clause (implicit inner join)
      -- has been replaced with a more modern explicit INNER JOIN, which
      -- works more clearly with the LEFT JOIN we need to do.
      Table1 t1
      INNER JOIN Table2 t2 ON t1.id = t2.id
      -- left join table 3 by tracker value
      LEFT JOIN Table3 t3 ON t2.tracker = t3.tracker
    WHERE t2.tracker IS NOT NULL
    GROUP BY
      t1.id,
      t2.tracker
    -- limit the group to only those with 1 tracker in t3
    HAVING COUNT(t3.tracker) = 1
    

    现在,您应该可以使用JOIN 将其填充到UPDATE 查询中。 MySQL 的 update-join 语法如下所示:

    UPDATE 
      Table1 t_up
      -- join Table1 in its normal form against the query from above
      -- MySQL won't allow an IN () subquery for update in most versions
      -- so it has to be done as a join instead.
      JOIN (
        -- the subquery only needs to return t1.id
        SELECT t1.id
        FROM 
          Table1 t1
          INNER JOIN Table2 t2 ON t1.id = t2.id
          LEFT JOIN Table3 t3 ON t2.tracker = t3.tracker
        -- Filter to those with non-null t2.tracker
        WHERE t2.tracker IS NOT NULL
        GROUP BY
          -- Since only id was in SELECT, only id needs to be in GROUP BY
          t1.id
        HAVING COUNT(t3.tracker) = 1
      ) t_set ON t_up.id = t_set.id
    SET t_up.some_field = 'SOME NEW VALUE'
    

    Here is a demonstration of the concept in action...

    【讨论】:

    • tracker字段不在表1中,只存在于表2和表3中,那么left join应该是针对表2的吧?可能是我的错,没有说清楚,对不起。
    • 好的,我会在几分钟后相应地更新它。
    • @user3314053 好的,我在上面和 sqlfiddle 示例中进行了更改。只需将LEFT JOIN 中的ON 条件更改为t2.tracker = t3.tracker.. 我实际上对此感到疑惑,因为tracker 将出现在所有3 个表中对我来说没有意义。无论如何,根据我的测试,它似乎确实有效。
    • 工作速度更快!谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 2011-06-14
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多