Oracle查询:非数值字段分组与指定格式输出的实现求助
Oracle SQL实现同一用户名仅首行显示的需求
你需要实现同一USRNAM值仅在所属分组的首行显示,其余行该字段为空的效果。当前查询使用GROUP BY的思路不适用,因为这个需求不是聚合统计,而是行级格式化展示,需要用窗口函数实现。
当前查询语句
Select userroles.usrnam,userroles.treeauth,roles.role from ROLES,USERROLES WHERE ROLES.TREEAUTH = USERROLES.TREEAUTH AND USRNAM in ('XXXX','YYYY') group by userroles.treeauth,roles.role;
现有表数据
| USRNAM | TREEAUTH | ROLE |
|---|---|---|
| YYYY | ML | Lab Manager |
| YYYY | TC | Lab-COA |
| YYYY | BB | B&S-Batch |
| YYYY | OR | Oper-Data-DCU |
| YYYY | L | IT - LIMS |
| YYYY | AD | Lab Admin |
| YYYY | DT | Data Users-Tags |
| YYYY | SP | Lab Special |
| XXXX | HD | Help Desk |
| YYYY | BS | B&S |
| YYYY | DC | Data Users |
| YYYY | TN | Lab |
| YYYY | BP | Planning-Batch |
| XXXX | L | IT - LIMS |
| YYYY | DB | B&S-Batch-Data |
| YYYY | DU | Data Users-COA |
期望输出格式
| USRNAM | TREEAUTH | ROLE |
|---|---|---|
| YYYY | ML | Lab Manager |
| TC | Lab-COA | |
| BB | B&S-Batch | |
| OR | Oper-Data-DCU | |
| L | IT - LIMS | |
| AD | Lab Admin | |
| DT | Data Users-Tags | |
| SP | Lab Special | |
| BS | B&S | |
| DC | Data Users | |
| TN | Lab | |
| BP | Planning-Batch | |
| DB | B&S-Batch-Data | |
| DU | Data Users-COA | |
| XXXX | HD | Help Desk |
| L | IT - LIMS |
解决方案
使用Oracle的ROW_NUMBER()窗口函数,按USRNAM分组并为每组内的行编号,再根据编号判断是否显示USRNAM值:
SELECT CASE WHEN rn = 1 THEN ur.usrnam ELSE '' END AS USRNAM, ur.treeauth, r.role FROM ( SELECT ur.usrnam, ur.treeauth, r.role, ROW_NUMBER() OVER (PARTITION BY ur.usrnam ORDER BY ur.treeauth) AS rn FROM ROLES r JOIN USERROLES ur ON r.TREEAUTH = ur.TREEAUTH WHERE ur.usrnam IN ('XXXX','YYYY') ) t ORDER BY ur.usrnam DESC, rn;
逻辑说明
- 子查询中通过
ROW_NUMBER() OVER (PARTITION BY ur.usrnam ORDER BY ur.treeauth)为每个USRNAM分组内的行生成序号,序号从1开始。ORDER BY ur.treeauth保证每组内行顺序一致,可按需修改排序字段。 - 外层查询用
CASE判断:若为组内第一行(rn=1),显示USRNAM值,否则显示空字符串。 - 最终通过
ORDER BY确保同一用户的行连续排列,这里用ur.usrnam DESC让YYYY排在前面,和期望输出一致,可按需调整排序规则。
内容的提问来源于stack exchange,提问作者Bala Meenakshi
相关产品推荐
相关产品推荐

