SQL中如何直接引用SELECT计算列创建新增列?
SQL中直接引用计算列生成新列的替代方案
我有如下SELECT语句,其中包含多个通过复杂CASE语句生成的Indicator列:
SELECT ID, NAME, AGE, LOCATION, GPF, ACCNO, CASE WHEN .... END AS Indicator1, CASE WHEN .... END AS Indicator2, .... FROM EMPLOYEES
目前我会用CTE或者临时表来基于这些Indicator列生成更多新列(甚至多层嵌套),但这两种方法运行耗时。想知道SQL中是否有其他方法,可以直接引用SELECT语句里的计算列(比如CASE结果)来创建新列?
可行的替代方案
1. 使用CROSS APPLY(推荐)
适用于SQL Server、PostgreSQL 10+、MySQL 8.0.14+等支持该语法的数据库。通过CROSS APPLY在FROM子句中预先计算出所有Indicator列,后续可以直接在主SELECT中引用,甚至多层嵌套生成新列,可读性和性能都较好。
示例代码:
SELECT e.ID, e.NAME, e.AGE, e.LOCATION, e.GPF, e.ACCNO, ind.Indicator1, ind.Indicator2, -- 直接引用Indicator列生成Class1 CASE WHEN ind.Indicator1 = 0 AND ind.Indicator2 = 1 THEN 'SDM1' -- 补充其他逻辑 END AS Class1, -- 基于Class1再生成新列 CASE WHEN Class1 = 'SDM1' THEN 'Category A' -- 补充其他逻辑 END AS Category FROM EMPLOYEES e CROSS APPLY ( SELECT CASE WHEN ... END AS Indicator1, CASE WHEN ... END AS Indicator2 -- 更多Indicator列 ) ind
2. 重复CASE表达式(仅简单场景可用)
直接在新列的CASE语句中嵌套原有的CASE逻辑,无需额外的CTE或临时表,但复杂场景会导致代码冗余、维护困难,且可能重复计算影响性能。
示例代码:
SELECT ID, NAME, AGE, LOCATION, GPF, ACCNO, CASE WHEN ... END AS Indicator1, CASE WHEN ... END AS Indicator2, CASE WHEN (CASE WHEN ... END) = 0 AND (CASE WHEN ... END) = 1 THEN 'SDM1' -- 补充其他逻辑 END AS Class1 FROM EMPLOYEES
3. 子查询嵌套
和CTE逻辑类似,但部分数据库的查询优化器可能对其生成不同的执行计划,可测试对比性能。
示例代码:
SELECT *, CASE WHEN Indicator1 = 0 AND Indicator2 = 1 THEN 'SDM1' -- 补充其他逻辑 END AS Class1, -- 基于Class1生成新列 CASE WHEN Class1 = 'SDM1' THEN 'Category A' END AS Category FROM ( SELECT ID, NAME, AGE, LOCATION, GPF, ACCNO, CASE WHEN ... END AS Indicator1, CASE WHEN ... END AS Indicator2 -- 更多Indicator列 FROM EMPLOYEES ) sub_query
总结
- CROSS APPLY是最优方案,代码清晰,多数数据库优化器会将其与主查询合并执行,避免重复计算,性能优于CTE和临时表。
- 重复CASE表达式仅适合逻辑简单的场景,复杂场景不建议使用。
- 子查询嵌套的性能和CTE接近,可根据使用的数据库特性选择测试。
内容的提问来源于stack exchange,提问作者variable
相关产品推荐
相关产品推荐

