PostgreSQL中按noso获取不同state下的code、co唯一记录
数据筛选需求
现有如下数据表(同一noso下包含不同state、nodo的code与co记录):
| noso | nodo | code | co | do | state | line id |
|---|---|---|---|---|---|---|
| #S2233 | PR1 | A | 10 | 10 | done | 1 |
| #S2233 | PR1 | B | 15 | 15 | done | 2 |
| #S2233 | PR1 | C | 15 | 15 | done | 3 |
| #S2233 | PR1 | D | 15 | 15 | done | 4 |
| #S2233 | PR1 | E | 5 | 5 | done | 5 |
| #S2233 | PR2 | E | 5 | 0 | cancel | 6 |
| #S2233 | PR2 | F | 4 | 0 | cancel | 7 |
| #S2233 | PR3 | E | 5 | 0 | cancel | 8 |
| #S2233 | PR3 | F | 4 | 0 | cancel | 9 |
| #S2233 | PR3 | G | 7 | 0 | cancel | 10 |
| #S2233 | PR4 | E | 5 | 0 | cancel | 11 |
| #S2233 | PR4 | F | 4 | 0 | cancel | 12 |
| #S2233 | PR4 | G | 7 | 0 | cancel | 13 |
筛选规则
- 保留同一
noso下所有state = 'done'的记录(该状态无重复code,直接全量保留) - 补充同一
noso下state = 'cancel'的记录,但仅保留未在done状态中出现过的code,每个符合条件的code仅保留一条记录(nodo可任选对应行的取值)
期望结果
| noso | nodo | code | co | do | state | line id |
|---|---|---|---|---|---|---|
| #S2233 | PR1 | A | 10 | 10 | done | 1 |
| #S2233 | PR1 | B | 15 | 15 | done | 2 |
| #S2233 | PR1 | C | 15 | 15 | done | 3 |
| #S2233 | PR1 | D | 15 | 15 | done | 4 |
| #S2233 | PR1 | E | 5 | 5 | done | 5 |
| #S2233 | PR2 | F | 4 | 0 | cancel | 7 |
| #S2233 | PR3 | G | 7 | 0 | cancel | 10 |
解决方案(SQL实现)
以下SQL语句可实现上述筛选逻辑,适配多数关系型数据库:
WITH done_code_list AS ( -- 按noso分组提取所有done状态的code,支持多noso场景 SELECT DISTINCT noso, code FROM your_table WHERE state = 'done' ) -- 合并符合条件的记录 SELECT t.* FROM your_table t WHERE state = 'done' UNION ALL SELECT t.* FROM your_table t JOIN done_code_list d ON t.noso = d.noso WHERE t.state = 'cancel' AND t.code NOT IN (SELECT code FROM done_code_list WHERE noso = t.noso) -- 确保每个code只取一条,此处选择line_id最小的行,可根据需求调整规则(比如指定nodo) AND t.line_id = (SELECT MIN(line_id) FROM your_table WHERE noso = t.noso AND code = t.code AND state = 'cancel') ORDER BY t.noso, t.state DESC, t.code;
代码说明
done_code_listCTE:按noso分组提取已完成状态的code,避免跨noso的误判- 第一部分直接选取所有
done状态的记录 - 第二部分通过关联和排除逻辑,筛选出
cancel状态中未在done出现过的code,同时通过子查询确保每个code仅保留一条记录 - 最后按
noso、state(优先显示done)、code排序,与期望结果格式匹配
内容的提问来源于stack exchange,提问作者Erik
相关产品推荐
相关产品推荐

