You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将MySQL 8含OVER()的SQL查询降级适配MySQL 5.7

将MySQL 8窗口函数查询改写为MySQL 5.7兼容写法

针对查询1的改写

原查询(修正temembers笔误后):

SELECT SUM(COUNT(application.email)*members.referral_bonus) OVER() AS total_count 
FROM application
LEFT JOIN members ON members.re_link=application.aff_code
WHERE application.re_status='1' AND MONTH(application.completed_paydate)='$month'

MySQL 5.7不支持窗口函数,这里SUM(...) OVER()的作用是计算全局聚合总和。由于原查询没有GROUP BY,可以直接用普通聚合函数实现:

SELECT SUM(IF(members.referral_bonus IS NOT NULL, COUNT(application.email)*members.referral_bonus, 0)) AS total_count
FROM application
LEFT JOIN members ON members.re_link=application.aff_code
WHERE application.re_status='1' AND MONTH(application.completed_paydate)='$month'

如果原查询实际需要先按aff_code分组再求和,改用子查询实现:

SELECT SUM(group_total) AS total_count
FROM (
    SELECT COUNT(application.email) * members.referral_bonus AS group_total
    FROM application
    LEFT JOIN members ON members.re_link=application.aff_code
    WHERE application.re_status='1' AND MONTH(application.completed_paydate)='$month'
    GROUP BY application.aff_code, members.referral_bonus
) AS sub_query

针对查询2的改写

原查询:

SELECT aff_members.app_full_name, COUNT(application.email) AS NumberOfRe, 
       SUM(COUNT(application.email)*members.re_bonus) OVER(PARTITION BY application.aff_code) AS total_count 
FROM application
LEFT JOIN members ON members.re_link=application.aff_code
WHERE application.re_status='1' AND MONTH(application.completed_paydate)<='$last_month'
GROUP BY app_email

这里OVER(PARTITION BY application.aff_code)用于计算每个aff_code分组的总和,在MySQL 5.7中推荐用预计算分组总和再关联的方式实现(性能优于关联子查询):

SELECT 
    aff_members.app_full_name, 
    COUNT(application.email) AS NumberOfRe,
    aff_totals.total_count
FROM application
LEFT JOIN members ON members.re_link=application.aff_code
-- 预计算每个aff_code对应的总和
LEFT JOIN (
    SELECT 
        a2.aff_code,
        SUM(COUNT(a2.email) * m2.re_bonus) AS total_count
    FROM application a2
    LEFT JOIN members m2 ON m2.re_link = a2.aff_code
    WHERE a2.re_status='1' AND MONTH(a2.completed_paydate)<='$last_month'
    GROUP BY a2.aff_code
) AS aff_totals ON aff_totals.aff_code = application.aff_code
WHERE application.re_status='1' AND MONTH(application.completed_paydate)<='$last_month'
-- MySQL 5.7要求GROUP BY包含所有非聚合字段
GROUP BY app_email, aff_members.app_full_name, application.aff_code, aff_totals.total_count

如果偏好关联子查询的写法,也可以这样写:

SELECT 
    aff_members.app_full_name, 
    COUNT(application.email) AS NumberOfRe,
    (
        SELECT SUM(COUNT(a2.email) * m2.re_bonus)
        FROM application a2
        LEFT JOIN members m2 ON m2.re_link = a2.aff_code
        WHERE a2.re_status='1' 
          AND MONTH(a2.completed_paydate)<='$last_month'
          AND a2.aff_code = application.aff_code
        GROUP BY a2.aff_code
    ) AS total_count
FROM application
LEFT JOIN members ON members.re_link=application.aff_code
WHERE application.re_status='1' AND MONTH(application.completed_paydate)<='$last_month'
GROUP BY app_email, aff_members.app_full_name, application.aff_code

注意:原查询的GROUP BY app_email在MySQL 5.7的ONLY_FULL_GROUP_BY模式下会报错,必须把aff_members.app_full_name和application.aff_code也加入GROUP BY。

内容的提问来源于stack exchange,提问作者Talamproxy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 13:25:19