如何编写带复杂条件的SQL查询,筛选成员从未变更的乐队名称
问题解答
实现思路
- 按乐队(
band_id、band_name)分组,对同一乐队的所有成员做统一校验 - 核心校验逻辑:只要乐队存在任意一个不符合规则的成员,就直接剔除该乐队,最终留下的就是阵容从未变更的乐队
- 成员合规要求:
- 成员加入时间等于乐队成立时间:
date_join = active_years_begin - 成员退出时间等于乐队解散时间,或任意一方为NULL(乐队/成员仍在活跃):
(date_left IS NULL OR active_years_end IS NULL) OR date_left = active_years_end
- 成员加入时间等于乐队成立时间:
具体查询语句
通用SQL写法,兼容MySQL、PostgreSQL、SQLite等大部分主流数据库,替换语句中your_table_name为实际表名即可使用:
SELECT band_name FROM your_table_name GROUP BY band_id, band_name HAVING COUNT( CASE WHEN NOT ( date_join = active_years_begin AND ( (date_left IS NULL OR active_years_end IS NULL) OR date_left = active_years_end ) ) THEN 1 END ) = 0;
如果更习惯用子查询写法,也可以用如下版本:
SELECT DISTINCT band_name FROM your_table_name t1 WHERE NOT EXISTS ( SELECT 1 FROM your_table_name t2 WHERE t2.band_id = t1.band_id AND NOT ( t2.date_join = t2.active_years_begin AND ( (t2.date_left IS NULL OR t2.active_years_end IS NULL) OR t2.date_left = t2.active_years_end ) ) );
结果验证
对你提供的样例数据执行语句后,返回结果和预期完全一致:
- The Beatles
- Wings
- Band1
- Band2
- Band3
- Band4
补充说明:样例中的Band5被排除,是因为乐队成立时间为2018-09-01,但成员加入时间为2021-09-01,存在中途加入成员的情况,不符合“阵容从未变更”的要求。
内容的提问来源于stack exchange,提问作者dasfex
相关产品推荐
相关产品推荐

