以下是一个录取学生人数表的示例,记录了每年录取学生的人数和入学学制。
id | year | num | stu_len |
---|---|---|---|
1 | 2018 | 101 | 3 |
2 | 2019 | 121 | 4 |
3 | 2020 | 91 | 2 |
4 | 2021 | 151 | 3 |
5 | 2021 | 141 | 2 |
6 | 2022 | 161 | 3 |
字段解释:
- id:记录的唯一标识符
- year:学生入学年度
- num:对应年度录取的学生人数
- stu_len:录取学生的学制
举例说明:例如,录取年度为2018的学制为3,表示这批学生在校的学习时间为20182019、20192020、2020~2021三个学年。
根据以上示例计算出每年在校人数,写出SQL语句:
1、数据准备
CREATE TABLE `test01` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`year` int(255) DEFAULT NULL COMMENT '入学年度',
`num` int(255) DEFAULT NULL COMMENT '录取学生人数',
`stu_len` varchar(255) DEFAULT NULL COMMENT '学生学制',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='录取人数';
INSERT INTO `test01` (`year`, `num`, `stu_len`) VALUES
(2018, 101, '3'),
(2019, 121, '4'),
(2020, 91, '2'),
(2021, 151, '3'),
(2021, 141, '2'),
(2022, 161, '3');
2、sql
思路1(笛卡尔积,性能较差):
select t_year.year,
-- sum() 就是一个累加的过程(累加器),如果为true就执行sum+num,为false就执行sum+0
sum(case when t_admit.start<=t_year.year and t_year.year<t_admit.end THEN num else 0 end ) stu_sum
from
(select distinct year from test01) as t_year,
(select id, num, year as start, year+stu_len as end from test01) as t_admit
GROUP BY t_year.year;
思路2:
SELECT t_year.year, SUM(t_admit.num) AS stu_sum
FROM (
SELECT DISTINCT year
FROM test01
) AS t_year
JOIN test01 AS t_admit ON t_year.year BETWEEN t_admit.year AND t_admit.year + t_admit.stu_len - 1
GROUP BY t_year.year;
explain查看执行计划: