繁体   English   中英

使用聚合函数的结果更新mySQL表

[英]Update mySQL Table with Results of Aggregate Function

我有一个汇总表和一个详细表,其中包含许多不同游戏的得分。 详细信息表包含数百万条记录,汇总表仅包含每个游戏和不同天数的平均得分。

例:
汇总表:

| ID | Name  | AVG_SCORE_7_DAYS | AVG_SCORE_30_DAYS |
-----------------------------------------------------
| 1  | Game 1| 10.3             | 20.3              |
| 2  | Game 2| 14.3             | 26.3              |

明细表:

| ID | Name  | Date                | Score |
--------------------------------------------
| 1  | Game 1| 2015-07-12 01:00:00 | 20    |
| 2  | Game 2| 2015-07-12 01:00:00 | 26    |
| 3  | Game 1| 2015-07-12 01:00:00 | 14    |
| 4  | Game 2| 2015-07-12 01:00:00 | 9     |

我使用如下代码通过存储过程每晚更新我的聚合表:

UPDATE `aggregate` aggr
INNER JOIN
(
    SELECT game_name, avg(score) AS avg_score
    FROM `detail`
    WHERE `date` BETWEEN (CURDATE() + INTERVAL -7 DAY) AND CURDATE()
    GROUP BY `game_name`
) detail7 ON aggr.`game_name` = detail7.`game_name`
INNER JOIN
(
    SELECT game_name, avg(score) AS avg_score
    FROM `detail`
    WHERE `date` BETWEEN (CURDATE() + INTERVAL -30 DAY) AND CURDATE()
    GROUP BY `game_name`
) detail30 ON aggr.`game_name` = detail30.`game_name`

我的问题是,如果在7天,30天等时间内某些游戏没有得分,那么这些子查询将不返回任何记录,因此,如果其中任何一个失败,则该游戏的所有列都不会更新(由于内部联接)。 有没有一种方法可以编写我的查询来更新其他列,即使子查询的结果不返回任何结果呢?

使用外部联接。 您还可以简化逻辑,因此仅需要一种聚合:

UPDATE `aggregate` aggr LEFT JOIN
        (SELECT game_name,
                avg(case when `date` BETWEEN (CURDATE() + INTERVAL -7 DAY) AND CURDATE() then score end) AS avg_score_07,
                avg(case when `date` BETWEEN (CURDATE() + INTERVAL -30 DAY) AND CURDATE() then score end) AS avg_score_30
         FROM `detail`
         WHERE `date` BETWEEN (CURDATE() + INTERVAL -30 DAY) AND CURDATE()
         GROUP BY `game_name`
        ) detail
        ON aggr.`game_name` = detail.`game_name`
    SET . . . ;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM