如何在执行查询前检测MySQL对row_number()函数的兼容性
检测row_number()函数支持性的方案
方案1:通用轻量预检测
直接执行无业务依赖的测试语句,执行成功则说明环境支持row_number()窗口函数,失败则不支持:
SELECT row_number() OVER () AS test_rn LIMIT 1
检测逻辑:
- 语句返回正常:可正常执行业务查询
- 语句报错:环境不支持窗口函数,可走降级查询逻辑
方案2:结合数据库版本判断(更适合已知数据库类型的场景)
不同数据库对窗口函数的支持版本下限不同,可先查询数据库版本判断兼容性:
- MySQL:8.0及以上版本支持,检测语句:
SELECT VERSION() - PostgreSQL:8.4及以上版本支持
- SQL Server:2005及以上版本支持
- Oracle:10g及以上版本支持
不支持row_number()时的降级查询方案
如果检测到环境不支持窗口函数,可改用关联子查询实现原语句的「按天取播放量前N条、再按天汇总播放量」的逻辑,你原有的业务查询语句如下:
SELECT stat_day, sum(total_count) as total_count FROM ( SELECT date(c_date) AS stat_day, media_id, artist, title, SUM(c_play) AS total_count , row_number() over (partition by date(c_date) order by sum(c_play) desc) as rn FROM {$statistics_table} WHERE c_date > NOW() - INTERVAL %d DAY GROUP BY date(c_date), media_id, artist, title HAVING SUM(c_play) > 0 ) t WHERE t.rn <= %d GROUP BY stat_day ORDER BY stat_day
对应的降级改写示例(无需窗口函数):
SELECT date(t1.c_date) AS stat_day, SUM(t1.c_play) AS total_count FROM {$statistics_table} t1 WHERE t1.c_date > NOW() - INTERVAL %d DAY GROUP BY date(t1.c_date), t1.media_id, t1.artist, t1.title HAVING SUM(t1.c_play) > 0 AND ( SELECT COUNT(*) FROM {$statistics_table} t2 WHERE date(t2.c_date) = date(t1.c_date) GROUP BY date(t2.c_date), t2.media_id, t2.artist, t2.title HAVING SUM(t2.c_play) > SUM(t1.c_play) ) < %d GROUP BY stat_day ORDER BY stat_day
内容的提问来源于stack exchange,提问作者Toniq
相关产品推荐
相关产品推荐

