如何用SQL判断学生在指定年度区间内是否满足var1=a的条件
SQL需求实现:按自定义年度区间判断学生记录存在性
现有表结构与数据
现有表df,日期字段为DATE格式,结构及数据如下:
| student | var1 | start | end |
|---|---|---|---|
| 1 | a | 2010-01-01 | 2013-01-01 |
| 1 | b | 2010-01-01 | 2013-01-01 |
| 1 | b | 2013-05-05 | 2015-09-09 |
| 1 | a | 2017-10-10 | 2018-09-01 |
| 2 | c | 2010-01-01 | 2014-01-01 |
| 2 | a | 2015-01-01 | 2017-09-01 |
| 2 | b | 2019-01-01 | 2023-03-05 |
需求说明
- 统计范围:2010年至2020年
- 针对每个学生,在每年3月1日至次年3月1日的区间内,判断是否至少有一条
var1='a'的记录 - 满足条件返回
TRUE,否则返回FALSE(无对应年份信息时也返回FALSE)
预期结果
| SN | Student | start_time | end_time | at_least_one_var1_a |
|---|---|---|---|---|
| 1 | 1 | 2010-03-01 | 2011-03-01 | TRUE |
| 2 | 1 | 2011-03-01 | 2012-03-01 | TRUE |
| 3 | 1 | 2012-03-01 | 2013-03-01 | TRUE |
| 4 | 1 | 2013-03-01 | 2014-03-01 | FALSE |
| 5 | 1 | 2014-03-01 | 2015-03-01 | FALSE |
| 6 | 1 | 2015-03-01 | 2016-03-01 | FALSE |
| 7 | 1 | 2016-03-01 | 2017-03-01 | FALSE |
| 8 | 1 | 2017-03-01 | 2018-03-01 | TRUE |
| 9 | 1 | 2018-03-01 | 2019-03-01 | TRUE |
| 10 | 1 | 2019-03-01 | 2020-03-01 | FALSE |
| 11 | 2 | 2010-03-01 | 2011-03-01 | FALSE |
| 12 | 2 | 2011-03-01 | 2012-03-01 | FALSE |
| 13 | 2 | 2012-03-01 | 2013-03-01 | FALSE |
| 14 | 2 | 2013-03-01 | 2014-03-01 | FALSE |
| 15 | 2 | 2014-03-01 | 2015-03-01 | TRUE |
| 16 | 2 | 2015-03-01 | 2016-03-01 | TRUE |
| 17 | 2 | 2016-03-01 | 2017-03-01 | TRUE |
| 18 | 2 | 2017-03-01 | 2018-03-01 | TRUE |
| 19 | 2 | 2018-03-01 | 2019-03-01 | FALSE |
| 20 | 2 | 2019-03-01 | 2020-03-01 | FALSE |
我的尝试与问题
我尝试通过以下步骤实现,但遇到了问题:
步骤1:创建日期区间CTE
WITH step1 AS ( SELECT '2010-03-01' AS start_date, '2011-03-01' AS end_date UNION ALL SELECT '2011-03-01', '2012-03-01' UNION ALL SELECT '2012-03-01', '2013-03-01' UNION ALL SELECT '2013-03-01', '2014-03-01' UNION ALL SELECT '2014-03-01', '2015-03-01' UNION ALL SELECT '2015-03-01', '2016-03-01' UNION ALL SELECT '2016-03-01', '2017-03-01' UNION ALL SELECT '2017-03-01', '2018-03-01' UNION ALL SELECT '2018-03-01', '2019-03-01' UNION ALL SELECT '2019-03-01', '2020-03-01' )
步骤2:关联查询学生数据(返回空结果)
joined_data AS ( SELECT t.student, d.start_date, d.end_date, t.var1 FROM df t JOIN date_ranges d ON t.start <= d.end_date AND t.end >= d.start_date )
这里的问题是joined_data返回空结果,后续原本计划用CASE WHEN统计:
var1_counts AS ( SELECT student, start_date, end_date, COUNT(CASE WHEN var1 = 'a' THEN 1 END) AS var1_count FROM joined_data GROUP BY student, start_date, end_date ) SELECT student, start_date, end_date, CASE WHEN var1_count > 0 THEN 'Yes' ELSE 'No' END AS at_least_one_var1_a FROM var1_counts;
希望在不使用交叉连接、关联查询或递归查询的前提下解决该问题,目前正在研究TO_CHAR()、TO_DATE()、CAST()、DATE_PART()及DATE_TRUNC()函数的用法。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

