如何复用SQL查询语句统计多组日期区间的数据?
最优方案及替代实现
1. 单查询内用条件聚合(性能最优)
直接在同一次查询里通过CASE WHEN区分两个日期区间,一次扫描表就能同时得到count1和count2,避免多次查询带来的重复表扫描,这是性能最好的方式:
SELECT COUNT(CASE WHEN birth_date >= TO_DATE(:start_date1, 'YYYY/MM/DD') AND birth_date <= TO_DATE(:end_date1, 'YYYY/MM/DD') THEN 1 END) AS count1, COUNT(CASE WHEN birth_date >= TO_DATE(:start_date2, 'YYYY/MM/DD') AND birth_date <= TO_DATE(:end_date2, 'YYYY/MM/DD') THEN 1 END) AS count2 FROM TABLE;
也可以用SUM实现相同效果:
SELECT SUM(CASE WHEN birth_date BETWEEN TO_DATE(:start_date1, 'YYYY/MM/DD') AND TO_DATE(:end_date1, 'YYYY/MM/DD') THEN 1 ELSE 0 END) AS count1, SUM(CASE WHEN birth_date BETWEEN TO_DATE(:start_date2, 'YYYY/MM/DD') AND TO_DATE(:end_date2, 'YYYY/MM/DD') THEN 1 ELSE 0 END) AS count2 FROM TABLE;
2. 封装成可复用的函数/存储过程
如果不想重复编写核心统计逻辑,可以把查询封装成自定义函数(以下以Oracle环境为例,语法可根据使用的数据库调整),之后传入不同日期参数调用即可:
封装函数示例:
CREATE OR REPLACE FUNCTION count_birth_date(p_start_date VARCHAR2, p_end_date VARCHAR2) RETURN NUMBER IS v_count NUMBER; BEGIN SELECT COUNT(*) INTO v_count FROM TABLE WHERE birth_date >= TO_DATE(p_start_date, 'YYYY/MM/DD') AND birth_date <= TO_DATE(p_end_date, 'YYYY/MM/DD'); RETURN v_count; END; /
调用获取两个统计值:
SELECT count_birth_date(:start_date1, :end_date1) AS count1, count_birth_date(:start_date2, :end_date2) AS count2 FROM DUAL;
这种方式虽然会执行两次表扫描,但好处是不用重复编写统计规则,适合需要多次复用该逻辑的场景。
内容的提问来源于stack exchange,提问作者Zaraki Kenpaachi
相关产品推荐
相关产品推荐

