MySQL更新查询与左连接和分组依据

Posted

技术标签:

【中文标题】MySQL更新查询与左连接和分组依据【英文标题】:MySQL Update query with left join and group by 【发布时间】:2011-03-02 15:11:13 【问题描述】:

我正在尝试创建更新查询,但在获取正确语法方面进展甚微。 以下查询正在运行:

SELECT t.Index1, t.Index2, COUNT( m.EventType ) 
    FROM Table t
    LEFT JOIN MEvents m ON
        (m.Index1 = t.Index1 AND
         m.Index2 = t.Index2 AND
        (m.EventType =  'A' OR m.EventType =  'B')
    ) 
    WHERE (t.SpecialEventCount IS NULL)
    GROUP BY t.Index1, t.Index2

它创建一个三元组 Index1、Index2、EventCounts 的列表。 它仅适用于 t.SpecialEventCount 为 NULL 的情况。我尝试编写的更新查询应将此 SpecialEventCount 设置为该计数,即上述查询中的 COUNT(m.EventType)。这个数字可以是 0 或任何正数(因此是左连接)。 Index1和Index2在Table t中是唯一的,用于标识MEvent中的事件。

如何将选择查询修改为更新查询? IE。像

UPDATE Table SET SpecialEventCount=COUNT(m.EventType).....

但我很困惑该放什么,并且因无数不同的猜测而失败。

【问题讨论】:

【参考方案1】:

我的例子

update card_crowd  as cardCrowd
LEFT JOIN 
(
select cc.id , count(1) as num
from card_crowd cc LEFT JOIN 
card_crowd_r ccr on cc.id = ccr.crowd_id
group by cc.id
) as tt
on cardCrowd.id = tt.id
set cardCrowd.join_num = tt.num;

【讨论】:

【参考方案2】:

对子查询进行左连接会产生一个巨人 内存中没有索引的临时表。

对于更新,请尝试避免连接并使用相关 子查询:

UPDATE
    Table AS t
SET
    t.SpecialEventCount = (
        SELECT COUNT(m.EventType)
        FROM MEvents m
        WHERE m.EventType in ('A','B')
          AND m.Index1 = t.Index1
          AND m.Index2 = t.Index2
    )
WHERE
    t.SpecialEventCount IS NULL

进行一些分析,但在某些情况下这可能会明显更快。

【讨论】:

对更新语句的提前分析并未得到广泛支持,因此通常必须实际执行才能对其进行测试。以这种方式将表中的所有 119465 行更新到 180 万行的表使用您的方法需要 0.7680 秒,使用 Hammerite 方法需要 0.6227 秒。我会说,那里没有戏剧。请注意,这可能因情况而异。我再次尝试链接到一个 18 百万的表,其中的数字分别为 23.9238 秒和 9.1261 秒。没有改进。【参考方案3】:

我认为(Index1, Index2)Table 上的唯一键,否则我预计对t.SpecialEventCount 的引用会导致错误。

已编辑查询以使用子查询,因为它无法使用 GROUP BY

UPDATE
    Table AS t
    LEFT JOIN (
        SELECT
            Index1,
            Index2,
            COUNT(EventType) AS NumEvents
        FROM
            MEvents
        WHERE
            EventType = 'A' OR EventType = 'B'
        GROUP BY
            Index1,
            Index2
    ) AS m ON
        m.Index1 = t.Index1 AND
        m.Index2 = t.Index2
SET
    t.SpecialEventCount = m.NumEvents
WHERE
    t.SpecialEventCount IS NULL

【讨论】:

谢谢,看起来与我尝试过的许多事情相似。不幸的是,返回以下错误:#1064 - 您的 SQL 语法有错误;检查与您的 mysql 服务器版本相对应的手册,以在第 9 行的 'GROUP BY t.Index1, t.Index2' 附近使用正确的语法 如果有帮助,请使用 5.0.90-log 版本 上面的问题是区分 0 和 NULL。如果没有匹配的事件,则 t.SpecialEventCount 设置为 NULL 而不是 0,因此您的表中总是会出现很多 NULL,而您不知道这些是零还是尚未计算。尝试设置 ... = IF(m.NumEvents IS NULL,0,m.NumEvents) 没有成功 SET t.SpecialEventCount = m.NumEvents 更改为SET t.SpecialEventCount = IFNULL(m.NumEvents, 0) 不错,使用 LEFT JOIN 语句的 UPDATE 可以正常工作,否则不行

以上是关于MySQL更新查询与左连接和分组依据的主要内容,如果未能解决你的问题,请参考以下文章

这个查询不好吗? MySql 一对多与左连接和嵌套查询

MySQL 索引优化与子查询与左连接

Clickhouse 数组连接与左连接和计算计数

右连接与左连接

mysql左连接没有数据还会查出来吗

数据库表连接(内连接,外连接左连接右连接全连接交叉连接)