如何筛选PS_JOB表中USRID重复且PER_ORG为EMP/CWR时保留EMP记录
嘿,这个需求我之前帮同事处理过类似的,给你几个实用的SQL实现方案,适配不同的数据库场景哈!
解决方案:筛选PS_JOB表的用户记录
先再明确下需求避免理解偏差:
- 同一
USRID对应多行,且同时包含PER_ORG='EMP'和PER_ORG='CWR':只保留EMP的记录 - 同一
USRID只有一行,且PER_ORG='CWR':保留该行 - 其他情况(比如只有EMP、或者有其他PER_ORG值):正常保留对应行(如果不需要这类行可以自行调整逻辑)
方案1:窗口函数实现(推荐,支持MySQL 8+/PostgreSQL/Oracle等现代数据库)
窗口函数可以给每个用户的分组标记优先级,然后筛选出符合要求的行,逻辑清晰还容易扩展:
WITH ranked_jobs AS ( SELECT *, -- 给EMP设最高优先级1,CWR设2,其他值设3 CASE PER_ORG WHEN 'EMP' THEN 1 WHEN 'CWR' THEN 2 ELSE 3 END AS priority, -- 按USRID分组,按priority排序生成行号 ROW_NUMBER() OVER (PARTITION BY USRID ORDER BY priority) AS rn FROM PS_JOB ) -- 替换成你实际需要保留的列 SELECT USRID, PER_ORG, /* 其他列比如JOB_TITLE, CREATE_DATE等 */ FROM ranked_jobs -- 只保留每个用户组里优先级最高的第一行 WHERE rn = 1
以后如果新增其他PER_ORG值,只要调整CASE里的优先级数字就行,扩展性拉满。
方案2:子查询实现(兼容低版本MySQL等不支持窗口函数的数据库)
如果你的数据库版本比较老,用子查询也能搞定,逻辑同样直接:
SELECT j.* FROM PS_JOB j WHERE -- 情况1:当前行是EMP,且该用户确实存在EMP记录 (j.PER_ORG = 'EMP' AND EXISTS ( SELECT 1 FROM PS_JOB j2 WHERE j2.USRID = j.USRID AND j2.PER_ORG = 'EMP' )) -- 情况2:当前行是CWR,且该用户没有EMP记录 OR (j.PER_ORG = 'CWR' AND NOT EXISTS ( SELECT 1 FROM PS_JOB j2 WHERE j2.USRID = j.USRID AND j2.PER_ORG = 'EMP' )) -- 情况3:其他PER_ORG值的行直接保留(不需要的话删掉这一行即可) OR j.PER_ORG NOT IN ('EMP', 'CWR')
验证小技巧
可以先跑下面的查询,看看目标用户的分组情况,确认筛选逻辑是否符合预期:
SELECT USRID, GROUP_CONCAT(DISTINCT PER_ORG ORDER BY PER_ORG) AS org_list, COUNT(*) AS row_count FROM PS_JOB GROUP BY USRID HAVING org_list IN ('EMP,CWR', 'CWR') -- 只看我们重点关注的分组 ORDER BY USRID
先确认这些分组的原始数据,再对比筛选后的结果,确保没有问题。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

