Oracle SQL查询中引用列别名避免重复计算的实现方法
实现方案
完全可以实现无需重复计算sum(bytes)、直接引用列别名的需求,Oracle 不支持同层级 SELECT 语句内引用刚定义的列别名,所以可以通过WITH 公用表表达式分层计算或者嵌套子查询的方式实现,其中WITH方案可读性更高,也适配你10张以上无关联表取数的场景。
推荐方案:WITH 分层计算
将基础指标查询、单位换算拆分为不同层级,上层可以直接引用下层定义的所有别名,所有基础值仅计算一次:
WITH base_metrics AS ( -- 第一层:统一查询所有无关联表的基础指标,仅执行一次原始查询 SELECT (SELECT name FROM v$database) AS "Database", (SELECT sum(bytes) FROM v$datafile) AS DB_SIZE_IN_Bytes -- 其他10+张无关联表的指标都可以在这里加,单独用标量子查询取,无需关联 FROM dual ), calc_kb AS ( -- 引用第一层的字节数计算KB SELECT base_metrics.*, DB_SIZE_IN_Bytes / 1024 AS DB_SIZE_IN_KBs FROM base_metrics ), calc_mb AS ( -- 引用第二层的KB计算MB SELECT calc_kb.*, DB_SIZE_IN_KBs / 1024 AS DB_SIZE_IN_MBs FROM calc_kb ), calc_gb AS ( SELECT calc_mb.*, DB_SIZE_IN_MBs / 1024 AS DB_SIZE_IN_GBs FROM calc_mb ), calc_tb AS ( SELECT calc_gb.*, DB_SIZE_IN_GBs / 1024 AS DB_SIZE_IN_TBs FROM calc_gb ) -- 最终输出所有维度的指标 SELECT "Database", DB_SIZE_IN_Bytes, DB_SIZE_IN_KBs, DB_SIZE_IN_MBs, DB_SIZE_IN_GBs, DB_SIZE_IN_TBs FROM calc_tb;
简化方案:嵌套子查询
如果换算层级少,也可以用嵌套子查询实现,逻辑和WITH一致,只是可读性稍差:
SELECT "Database", DB_SIZE_IN_Bytes, DB_SIZE_IN_KBs, DB_SIZE_IN_KBs / 1024 AS DB_SIZE_IN_MBs, DB_SIZE_IN_KBs / 1024 /1024 AS DB_SIZE_IN_GBs, DB_SIZE_IN_KBs / 1024 /1024 /1024 AS DB_SIZE_IN_TBs FROM ( SELECT "Database", DB_SIZE_IN_Bytes, DB_SIZE_IN_Bytes / 1024 AS DB_SIZE_IN_KBs FROM ( SELECT (SELECT name FROM v$database) AS "Database", (SELECT sum(bytes) FROM v$datafile) AS DB_SIZE_IN_Bytes FROM dual ) base ) kb_calc;
适配多表场景说明
你实际项目中涉及10张以上无关联列的表时,所有表的基础查询都可以放到最内层的基础指标层,每个指标用独立的标量子查询取值即可,不需要做任何表关联操作,后续所有计算都直接引用基础层的别名,不会重复执行原始的表查询、聚合计算,性能远优于重复写聚合逻辑的写法。
内容的提问来源于stack exchange,提问作者Ali R. Memon
相关产品推荐
相关产品推荐

