Oracle数据库同表自对比查询的表列别名命名方法与错误解决
1 Oracle表与列别名的正确语法
你最初语句的报错是因为Oracle不支持在表别名后直接通过括号批量定义列别名的语法,该写法仅在PostgreSQL等少数数据库中可用,同时你原语句还存在字段名拼写错误(将nameClient写为nomClient)、NATURAL JOIN逻辑不合理的问题。
Oracle的别名规则如下:
- 表别名:直接在表名后添加别名,关键字
AS可省略,写法示例:FROM Client c - 列别名:在SELECT子句的字段后单独定义,关键字
AS可省略,若别名含特殊字符需用双引号包裹,写法示例:SELECT c2.nameClient AS nameClient2
修正后的自连接语句如下:
SELECT c.nameClient, c2.nameClient AS nameClient2 FROM Client c JOIN Client c2 ON c.noTelephone = c2.noTelephone WHERE c.nameClient < c2.nameClient
2 同表对比字段的优化实现方式
你当前使用的自连接写法适合需要输出两两配对的重复客户的场景,如果你只需要列出所有存在手机号重复的客户,以下两种写法性能更优:
2.1 分组预过滤法
先筛选出有重复的手机号,再关联查询对应客户,逻辑直观易维护:
WITH duplicate_tel AS ( SELECT noTelephone FROM Client GROUP BY noTelephone HAVING COUNT(1) > 1 ) SELECT noTelephone, noClient, nameClient FROM Client WHERE noTelephone IN (SELECT noTelephone FROM duplicate_tel) ORDER BY noTelephone;
2.2 分析函数法
仅需一次全表扫描即可得到结果,大数据量表下性能远高于自连接写法:
SELECT noTelephone, noClient, nameClient FROM ( SELECT noTelephone, noClient, nameClient, COUNT(1) OVER(PARTITION BY noTelephone) AS tel_count FROM Client ) WHERE tel_count > 1 ORDER BY noTelephone;
两种优化写法都可以避免自连接产生的额外笛卡尔积开销,适合数据量较大的生产环境使用。
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

