如何优化SQL:筛选布尔值并获取重复idcrsp的最早日期记录
问题:筛选同时包含布尔值的idcrsp并保留最早日期记录
我需要优化SQL查询,实现两个核心需求:
- 仅选取同时包含true和false布尔值的idcrsp记录,单一布尔值的idcrsp直接排除
- 对筛选后的重复idcrsp,仅保留日期最早的那条记录
示例数据库数据
| id | idcrsp | date | boolean |
|---|---|---|---|
| 1 | 100 | 11-2022 | true |
| 2 | 100 | 07-2022 | false |
| 3 | 200 | 06-2022 | false |
| 4 | 300 | 09-2022 | true |
| 5 | 300 | 08-2022 | false |
| 6 | 400 | 10-2022 | false |
| 7 | 100 | 01-2022 | false |
| 8 | 100 | 02-2022 | false |
当前SQL语句
SELECT true_table.* FROM mydb as true_table INNER JOIN (SELECT * FROM mydb WHERE requalif=TRUE) as false_table ON true_table.idcrsp = false_table.idcrsp AND true_table.requalif = FALSE;
当前查询结果
| id | idcrsp | date | boolean |
|---|---|---|---|
| 8 | 100 | 02-2022 | false |
| 7 | 100 | 01-2022 | false |
| 2 | 100 | 07-2022 | false |
| 5 | 300 | 08-2022 | false |
优化后的SQL方案
使用窗口函数ROW_NUMBER()结合CTE(公共表表达式),一步完成筛选和去重需求,逻辑更清晰且性能更优:
WITH qualified_ids AS ( -- 筛选同时包含true和false的idcrsp SELECT idcrsp FROM mydb GROUP BY idcrsp HAVING COUNT(DISTINCT boolean) = 2 ), ranked_records AS ( -- 对符合条件的记录按idcrsp分组,按日期升序编号 SELECT *, ROW_NUMBER() OVER (PARTITION BY idcrsp ORDER BY date ASC) AS rn FROM mydb WHERE idcrsp IN (SELECT idcrsp FROM qualified_ids) AND boolean = FALSE -- 匹配原查询仅取false记录的逻辑 ) -- 保留每个idcrsp的第一条(日期最早)记录 SELECT id, idcrsp, date, boolean FROM ranked_records WHERE rn = 1;
逻辑说明
qualified_ids:通过分组和HAVING条件,精准找出同时存在两种布尔值的idcrspranked_records:对符合条件的记录按idcrsp分组,按日期升序排序并为每条记录分配唯一编号- 最终筛选:只保留每个分组中编号为1的记录,即该idcrsp的最早日期记录
执行后会得到目标结果:
| id | idcrsp | date | boolean |
|---|---|---|---|
| 7 | 100 | 01-2022 | false |
| 5 | 300 | 08-2022 | false |
内容的提问来源于stack exchange,提问作者Ludo 45
相关产品推荐
相关产品推荐

