Oracle 的“老写法”本质上是ANSI SQL:1989 / SQL-92 之前的风格在金融、电信、银行系统里非常常见。下面按类型 示例 现代等价写法 踩坑点给你系统梳理一遍和你刚才那条 SQL 属于同一个“时代产物”。一、隐式连接Implicit JOIN✅ 你刚遇到的老写法SELECT*FROMEMP E,DEPT DWHEREE.DEPTNOD.DEPTNO;新写法SELECT*FROMEMP EJOINDEPT DONE.DEPTNOD.DEPTNO;本质逗号 CROSS JOINWHERE 过滤条件风险少写一个条件就变笛卡尔积二、()外连接Oracle 独有这是 Oracle 最著名的“老古董”。左外连接老SELECTE.ENAME,D.DNAMEFROMEMP E,DEPT DWHEREE.DEPTNOD.DEPTNO();左外连接新SELECTE.ENAME,D.DNAMEFROMEMP ELEFTJOINDEPT DONE.DEPTNOD.DEPTNO;右外连接老SELECTE.ENAME,D.DNAMEFROMEMP E,DEPT DWHEREE.DEPTNO()D.DEPTNO;规则口诀非常重要()写在“补空的一边”❌ 不支持全外连接FULL OUTER JOIN多个OR条件自连接 ()✅ Oracle 官方建议12c 以后尽量不用()三、DECODE替代 CASE老牌条件表达式老写法SELECTDECODE(SEX,1,男,2,女,未知)ASSEX_DESCFROMEMP;新写法SELECTCASESEXWHEN1THEN男WHEN2THEN女ELSE未知ENDASSEX_DESCFROMEMP;DECODE是 Oracle 私有函数CASE是 ANSI 标准可读性强四、NVLvsCOALESCE老写法SELECTNVL(COMM,0)FROMEMP;新写法SELECTCOALESCE(COMM,0)FROMEMP;对比项NVLCOALESCE标准Oracle 私有ANSI SQL参数个数2 个≥2 个短路求值❌✅COALESCE更安全尤其跨数据库五、SYSDATE 数字 日期运算老习惯老写法SELECTSYSDATE1FROMDUAL;-- 明天SELECTSYSDATE-1/24FROMDUAL;-- 一小时前新写法更语义化SELECTSYSDATEINTERVAL1DAYFROMDUAL;SELECTSYSDATE-INTERVAL1HOURFROMDUAL; 老写法在金融计息、账期计算中极常见 新写法可读性更好但性能没差别六、ROWNUM分页经典老写法老写法SELECT*FROM(SELECTA.*,ROWNUM RNFROM(SELECT*FROMEMPORDERBYHIREDATEDESC)AWHEREROWNUM20)WHERERN10;新写法12cSELECT*FROMEMPORDERBYHIREDATEDESCOFFSET10ROWSFETCHNEXT10ROWSONLY;ROWNUM是 Oracle 特有OFFSET / FETCH是 ANSI SQL七、SELECT COUNT(*) INTO V_CNT FROM ... WHERE ROWNUM1老写法判断是否存在SELECTCOUNT(*)INTOV_CNTFROMEMPWHEREDEPTNO10ANDROWNUM1;新写法SELECT1INTOV_FLAGFROMEMPWHEREDEPTNO10FETCHFIRST1ROWSONLY; 老写法是为了性能优化找到一条就停八、EXISTS里的SELECT 1老习惯老写法SELECT*FROMEMP EWHEREEXISTS(SELECT1FROMDEPT DWHERED.DEPTNOE.DEPTNO);说明SELECT 1是历史习惯Oracle 实际不关心 SELECT 列表SELECT NULL也一样 这是“老派写法”不是错误九、||字符串拼接Oracle 传统老写法SELECTA||BFROMDUAL;新写法ANSISELECTCONCAT(A,B)FROMDUAL;||是 Oracle / PostgreSQL 风格CONCAT在 MySQL / SQL Server 中更通用十、HINT写在注释里Oracle 特色老写法SELECT/* INDEX(E EMP_IDX) */*FROMEMP E; 注释不是注释是优化器指令 这种“伪装成注释的语法”是 Oracle 独有十一、你这条 SQL 里还藏着的“老味儿”结合你刚才的 SQL其实还有这些老特征特征老/新逗号 WHERE 关联老LAG 窗口函数新多层子查询老GROUP BY 长字段拼接老无 WITHCTE老无 JOIN ON老十二、总结一张对照表速查场景老写法新写法内连接, WHEREJOIN … ON外连接()LEFT/RIGHT JOIN条件分支DECODECASE空值处理NVLCOALESCE分页ROWNUMOFFSET/FETCH存在判断COUNT(*)ROWNUM1EXISTS FETCH十三、给你的实战建议很实用读老代码必须会老写法写新代码优先用 ANSI SQL重构老 SQL先不改逻辑只把, WHERE→JOIN ON性能别乱动老 SQL 很多“反直觉写法”是为性能服务的