PostgreSQL中如何循环合并查询?按测试获取唯一候选人ID
解决按测试维度获取唯一候选人ID的SQL问题
你当前的问题出在DISTINCT ON (candidate_Id)的用法上——它会让每个候选人只保留一条测试记录,直接过滤掉了同一候选人参加的其他测试数据。要实现「每个测试下返回唯一候选人ID,所有测试结果合并输出」的需求,核心是对测试ID+候选人ID的组合去重,而非仅对候选人ID去重。
以下是几种可行的解决方案:
方案1:修改DISTINCT ON的字段组合
针对PostgreSQL环境(DISTINCT ON是PostgreSQL特有语法),把去重字段从单一candidate_Id改成Test_id, candidate_Id,这样就能保证每个测试下的候选人唯一,同时保留所有测试的有效记录:
SELECT DISTINCT ON (Test_id, candidate_Id) candidate_Id, Test_id FROM [database] WHERE candidate_Id in ('[long list of ids]') AND Test_id in ('001','002','003','004','005','006','007','008') ORDER BY Test_id, candidate_Id; -- PostgreSQL要求DISTINCT ON的字段必须出现在ORDER BY中
方案2:使用普通DISTINCT
如果不需要PostgreSQL特有的DISTINCT ON逻辑,直接用普通DISTINCT即可,它会自动对选中的所有字段组合去重:
SELECT DISTINCT candidate_Id, Test_id FROM [database] WHERE candidate_Id in ('[long list of ids]') AND Test_id in ('001','002','003','004','005','006','007','008');
方案3:用GROUP BY分组去重
因为你只需要candidate_Id和Test_id两个字段,通过GROUP BY对这两个字段分组,同样能实现去重效果:
SELECT candidate_Id, Test_id FROM [database] WHERE candidate_Id in ('[long list of ids]') AND Test_id in ('001','002','003','004','005','006','007','008') GROUP BY Test_id, candidate_Id;
选择建议
- 如果只是单纯需要「测试-候选人」的唯一组合,三种方法效果一致;
- 如果后续需要在每个「测试-候选人」组合中提取特定数据(比如该候选人在该测试中的最新成绩),方案1的
DISTINCT ON配合ORDER BY(比如按测试时间排序)会更灵活。
内容的提问来源于stack exchange,提问作者user8272537
相关产品推荐
相关产品推荐

