AIR_USER表单个用户多客户编号查询及SQL语句优化咨询
语句正确性验证
你当前的SQL逻辑存在偏差:原语句通过GROUP BY LOGIN, CUST_NUM+HAVING COUNT(CUST_NUM) > 1,实际是找出同一LOGIN下重复出现的CUST_NUM(即同一个客户编号在同一个登录账号下多次存在),但你的需求是查询单个LOGIN对应的多个不同CUST_NUM,两者逻辑不匹配,语句不符合业务需求。
修正后的正确SQL语句
如果只是要获取有多个不同CUST_NUM的LOGIN及其对应的所有CUST_NUM:
SELECT a.LOGIN, a.CUST_NUM FROM AIR_USER a INNER JOIN ( -- 先筛选出拥有多个不同CUST_NUM的LOGIN SELECT LOGIN FROM AIR_USER GROUP BY LOGIN HAVING COUNT(DISTINCT CUST_NUM) > 1 ) b ON a.LOGIN = b.LOGIN ORDER BY a.LOGIN;
如果需要同时展示每个LOGIN下的CUST_NUM总数:
SELECT LOGIN, CUST_NUM, total_cust_count FROM ( SELECT LOGIN, CUST_NUM, -- 窗口函数统计每个LOGIN下的不同CUST_NUM数量 COUNT(DISTINCT CUST_NUM) OVER (PARTITION BY LOGIN) AS total_cust_count FROM AIR_USER ) t WHERE total_cust_count > 1 ORDER BY LOGIN;
性能优化方案
- 建立复合索引:创建
(LOGIN, CUST_NUM)的复合索引,分组、关联和排序操作都可以直接利用索引,避免全表扫描,大幅降低查询成本。 - 移除冗余语法:原语句中
GROUP BY已经会对结果去重,额外加DISTINCT完全多余,会增加不必要的计算开销。 - 优化排序逻辑:如果业务允许,优先去掉
ORDER BY;如果必须排序,上面的复合索引已经包含LOGIN,可以利用索引排序,避免内存排序的开销。 - 分区表优化:如果数据量持续增长,可考虑按
LOGIN或业务时间字段(若表中有)对AIR_USER表做分区,缩小查询时的扫描范围。
内容的提问来源于stack exchange,提问作者Cool_Oracle
相关产品推荐
相关产品推荐

