如何将SQL查询改写为WHERE子句不包含子查询的版本
SQL改写方案
完全可以实现,以下两种常用方案都可以移除WHERE子句中的子查询逻辑:
方案1:窗口函数实现(支持MySQL 8.0+、PostgreSQL、SQL Server、Oracle等所有支持窗口函数的SQL引擎)
select distinct ie.install_id, ie.sp_id, ie.device_config_id from ( select ie.install_id, ie.sp_id, ie.device_config_id, ie.install_dttm, max(ie.install_dttm) over (partition by ie.sp_id) as max_install_dttm from d1_sp sp inner join install_evt ie on ie.sp_id = sp.sp_id ) t where install_dttm = max_install_dttm
该方案将原本的关联子查询逻辑转移到内层查询的窗口函数中计算,外层WHERE仅做简单等值判断,无嵌套子查询。
方案2:预聚合关联实现(兼容不支持窗口函数的低版本SQL引擎)
select distinct ie.install_id, ie.sp_id, ie.device_config_id from d1_sp sp inner join install_evt ie on ie.sp_id = sp.sp_id inner join ( select sp_id, max(install_dttm) as max_install_dttm from install_evt group by sp_id ) iemax on ie.sp_id = iemax.sp_id and ie.install_dttm = iemax.max_install_dttm
该方案将原本的子查询改为FROM后的关联临时表,WHERE子句无任何查询逻辑,兼容性更强。
两种方案的执行结果和原SQL完全一致,若sp_id和install_dttm字段建有联合索引,两种方案的执行效率均不低于原SQL。
内容的提问来源于stack exchange,提问作者Punter Vicky
相关产品推荐
相关产品推荐

