mysql根据出生日期统计各年龄段男女人数

本文介绍了一种使用SQL进行年龄分段统计的方法,通过CASE WHEN语句结合GROUP BY实现不同年龄段的人数统计,特别关注于如何处理无记录年龄段的问题,并提供了一种后台处理策略,确保所有年龄段都有统计数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

表格名称 user, 字段 id, sex ( M 表示男, F表示 女), birthday出生日期, 没有 age字段

其中 ROUND(DATEDIFF(CURDATE(), birthday)/365.2422) 是获得 年龄

CASE WHEN的格式是:

CASE
   WHEN  ( 条件)  THEN  结果
   WHEN  ( 条件)  THEN  结果
   WHEN  ( 条件)  THEN  结果
END
SELECT nnd as ageRange,sex,count(*) as count from(
   SELECT
      CASE
         WHEN ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) >= 0
             and ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) <= 12 THEN '0-12岁'
         WHEN ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) >= 13 
             and ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) <= 17 THEN '13-17岁'
         WHEN ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) >= 18 
             and ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) <= 22 THEN '18-22岁'
         WHEN ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) >= 23
             and ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) <= 30 THEN '23-30岁'
         WHEN ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) >= 31 
             and ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) <= 59 THEN '31-59岁'
         WHEN ROUND(DATEDIFF(CURDATE(), people_birthday)/365.2422) >= 60 THEN '60岁以上'
      END as nnd
     ,people_sex as sex
   from people_info_sync
) a GROUP BY nnd,sex;

结果:
在这里插入图片描述
存在的缺点: 因为是使用 group by的方法, 所以如果没有记录的话, 是不会返回数据的,
除非你用 left join 新建一张表来存 “0-12岁”,“13-17岁”,“18-22岁”,“23-30岁”,“31-59岁”,"60岁以上"这些数据, 然后使用 左连接 left join , 这样就能保证一定会有这些数据。。。但你的组长是无论如何也不会允许你这么干的哈哈。。

写了一个后台处理的方法, 可以参考下

    /**
     * sql查询使用Group By方法,如果数据库本身没有那条记录的话,就不会返回相应的总数,所以需要定死数组,再通过遍历的方式去查找
     * @return
     */
    public List<CountAgeDto> countAge(){
        //这里就不能用 new String[]{"男","女"} 了,要和你数据库查出来的结果一样才行
        String[] sexArr = new String[]{"F","M"};
        String[] ageArr = new String[]{"0-12岁","13-17岁","18-22岁","23-30岁","31-59岁","60岁以上"};
        //从数据库获得数据, 这个countAge()方法要自己写,就执行上面的sql语句
        List<CountAgeDto> dataList =  peopleInfoSyncDao.countAge();
        //首先初始化
        List<CountAgeDto> countAgeDtoList = new ArrayList<>();
        for(String sex : sexArr){
            for(String age: ageArr){
                CountAgeDto countAgeDto = new CountAgeDto();
                countAgeDto.setAgeRange(age);
                countAgeDto.setSex(sex);
                //初始化为0, 确保都有值
                countAgeDto.setCount(0L);
                //遍历数据库查出来的集合
                if(dataList != null && dataList.size() > 0){
                    for(CountAgeDto d : dataList){
                        //如果和当前的sex和age相同,就说明count有值,则退出
                        if(d.getAgeRange().equals(age) && d.getSex().equals(sex)){
                            countAgeDto.setCount(d.getCount());
                            break;
                        }
                    }
                }
                countAgeDtoList.add(countAgeDto);
            }
        }
        return countAgeDtoList;
    }

其中CountAgeDto是:

public class CountAgeDto {
    /**
     * 总数
     */
    private Long count;
    /**
     * 年龄段
     */
    private String ageRange;
    /**
     * 性别
     */
    private String sex;

    public Long getCount() {
        return count;
    }

    public void setCount(Long count) {
        this.count = count;
    }

    public String getAgeRange() {
        return ageRange;
    }

    public void setAgeRange(String ageRange) {
        this.ageRange = ageRange;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "CountAgeDto{" +
                "count=" + count +
                ", ageRange='" + ageRange + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值