如何统计带内连接、WHERE子句与无过滤的SQL行数(规避子查询)
替代子查询的双计数SQL写法
原写法里的子查询会单独执行一次全表计数,既冗余又影响效率;如果内连接导致主表行重复,count(1)还可能统计出不符合预期的结果。下面是两种更合理的优化写法:
写法一:交叉连接聚合查询(通用型)
这种写法逻辑直白,所有SQL数据库都支持,两个计数查询独立执行,数据库可针对性优化执行计划:
SELECT 有效数据计数.ValidCount, 全表计数.AllCount FROM (SELECT COUNT(DISTINCT 主表.EmpId) AS ValidCount FROM TableAll 主表 INNER JOIN TableSelected 关联表 ON 主表.EmpId = 关联表.EmpId WHERE 主表.IsValid = 1) AS 有效数据计数 CROSS JOIN (SELECT COUNT(1) AS AllCount FROM TableAll) AS 全表计数;
注:如果确定关联表不会让主表行重复,可去掉DISTINCT以提升性能。
写法二:窗口函数单扫描写法(高性能型)
利用窗口函数仅扫描一次主表,数据量较大时性能更优,适合支持窗口函数的数据库(如MySQL 8.0+、PostgreSQL、SQL Server等):
SELECT 有效数据计数, 全表计数 FROM ( SELECT COUNT(DISTINCT CASE WHEN IsValid = 1 AND 关联表.EmpId IS NOT NULL THEN EmpId END) AS 有效数据计数, COUNT(*) OVER () AS 全表计数 FROM TableAll LEFT JOIN TableSelected 关联表 ON TableAll.EmpId = 关联表.EmpId ) AS 临时结果 LIMIT 1;
内容的提问来源于stack exchange,提问作者fdkgfosfskjdlsjdlkfsf
相关产品推荐
相关产品推荐

