不知道你啥数据库,如果是oracle,可以用分区索引,每个分区对应一个年龄段,这个查询0.1秒就可以搞定
分析下需求
1、年龄是什么?和生日的关系
这里面涉及到当前日期和生日的差距,是取整年份,还是四舍五入?
比如1980-01-01出生,今天2021-09-16日,是41岁,还是42岁?
我们用伪代码表示 CalAge(当前日期,生日) as age
无论哪种,年龄都是动态计算出的。
2、计算年龄对应的数量
select age,count(*) from T group by age order by age
这个简单的group就行了
3、性能
这是个伪需求,性能都是和环境有关的,特别是硬件。
唯一能考虑的,可能是在生日列建一个BT索引, 因为ID和Name列是完全没用的数据列。
看上去这个问题像是要考你索引的使用。你这查询必然要扫描全部数据的
所以首先你可以在日期那一列加索引,如果你的日期是年月日时分秒,那么要建函数索引trunc把时分秒去掉。如果日期是年月日,那么直接建即可,然后由于只会用到日期,所以查询应该会采用快速索引全扫描(我觉的这一点是你这个任务的考点)。
下面是我给你的一个列子,这个例子大概思路是这样的,首先通过日期group by得出每一天出身的人数有多少,然后将出生的人的出生日期和当前日期进行计算得出两者差了多少月并处以12得出年份,并向上取整,
例如2021年9月15号出身的,今天是2021年9月16号,因为小于0,因此那么这个人就是1岁
2020年9月15号出身的,今天是2021年9月16号,这个值是1.0几,向上取整因此这个人是两岁。
要在5秒内查出实际上方法有很多种,我下面这个查询用了并行查询,我加了提示使用并行查询/+ parallel(aa 8)/,所以2000万数据左右这个sql大约1秒左右可以出结果。你的题目我估计考的是索引的使用,所以这个提示在你的题目中应该是不应该用的。你去掉即可。
select age,sum(nums) from(
select /*+ parallel(aa 8)*/
ceil(months_between(sysdate, trunc(bdate)) / 12) age, count(*) nums
from TABLE AA
group by trunc(bdate)
) group by age