如何获取phone与email各自唯一的首个对应数据行?
解决方案:筛选phone和email各自唯一的首次出现行
首先明确需求:从PatientData表中提取一组行,要求phone列无重复值、email列也无重复值,且每个选中的行是对应phone/email在原表中最早出现的可行行(即该行的phone和email未被之前选中的行占用)。
方法:使用递归CTE按顺序筛选
这种方法会按原表的行顺序(这里以id_number降序匹配你给出的表顺序)依次遍历行,只保留那些phone和email都未被已选行占用的记录,最终得到符合要求的结果。
WITH ordered_data AS ( -- 先给表按指定顺序编号,这里用id_number降序对应你的原表排列 SELECT id_number, phone, email, dob, ROW_NUMBER() OVER (ORDER BY id_number DESC) AS row_num FROM PatientData ), recursive_pick AS ( -- 初始化:选取第一行 SELECT id_number, phone, email, dob, row_num FROM ordered_data WHERE row_num = 1 UNION ALL -- 递归逻辑:选取下一行,确保该行的phone和email都未被已选记录占用 SELECT od.id_number, od.phone, od.email, od.dob, od.row_num FROM ordered_data od JOIN recursive_pick rp ON od.row_num = rp.row_num + 1 WHERE NOT EXISTS ( SELECT 1 FROM recursive_pick rp_check WHERE rp_check.phone = od.phone OR rp_check.email = od.email ) ) -- 最终输出结果,按原顺序排列 SELECT id_number, phone, email, dob FROM recursive_pick ORDER BY id_number DESC;
方法说明
- ordered_data:先给表中的行按你需要的“首次出现”顺序编号(这里用
id_number降序,对应你给出的表中id6到id1的顺序)。 - recursive_pick:通过递归方式逐行筛选:
- 初始步骤先选第一行;
- 后续步骤每次检查下一行的phone和email是否已经在已选中的行里出现过,若未出现则选中该行。
- 最终输出的结果会自动满足phone和email各自唯一,且保留的是符合条件的最早出现行。
验证结果
执行上述SQL后,得到的结果与你期望的输出完全一致:
| id_number | phone | dob | |
|---|---|---|---|
| 6 | 04-------61 | example@gmail.com | 196949200 |
| 2 | 66-------61 | test@gmail.com | 596949200 |
| 1 | 77-------61 | another@gmail.com | 696949200 |
内容的提问来源于stack exchange,提问作者IndexZero
相关产品推荐
相关产品推荐

