如何在 WHERE 子句中使用临时列名?

Posted

技术标签:

【中文标题】如何在 WHERE 子句中使用临时列名?【英文标题】:How to use temporary column's name in WHERE clause? 【发布时间】:2021-04-03 10:20:26 【问题描述】:

首先,我不得不说,我在来这里之前已经研究过我的问题并看到了类似的question here 及其所有答案,但不幸的是它对我没有帮助。

Oracle SQL。

我有:

SELECT 
    first_name, 
    salary_dollars, 
    0.85 * salary_dollars AS salary_euro
FROM 
    employees 
WHERE 
    0.85 * salary_dollars > 4000;

salary_euro 是我的临时专栏。我想避免在WHERE 子句中进行双重计算,但是如果我在请求中写WHERE salary_euro > 4000,则会收到此错误:

ORA-00904:“SALARY_EURO”:标识符无效 00904. 00000 - “%s:无效标识符” *原因: *行动: 行错误:6 列:7

【问题讨论】:

【参考方案1】:

绕过此限制的一种方法是使用子查询来创建临时列:

SELECT * 
FROM   (SELECT first_name, 
               salary_dollars, 
               0.85 * salary_dollars AS salary_euro
       FROM    employees) e
WHERE  salary_euro > 4000;

【讨论】:

非常感谢 Mureinik,我们真的需要 'e' 吗?因为它在没有“e”的情况下也可以工作 这是整个子查询(作为内联视图)的 别名。如果 Mureinik 将它用于例如where e.salary.euro > 4000select 语句的列列表(而不是星号)。但是,是的,没有它也可以。 @StanlyT 在 Oracle SQL 中,您并不严格需要它,正如您所指出的。其他一些 RDMBS 需要它,所以我发现添加它是一个好习惯。【参考方案2】:

Oracle 现在支持横向连接。这允许您将定义移动到FROM 子句:

SELECT e.first_name, e.salary_dollars, x.salary_euro    
FROM employees e CROSS JOIN LATERAL
     (SELECT 0.85 * e.salary_dollars AS salary_euro FROM DUAL
     ) x
WHERE x.salary_euro > 4000;

横向连接使定义计算链变得更简单,因为下一个表达式可以依赖于前一个。

当然,使用 CTE 或子查询的传统方法也相当可行。

【讨论】:

以上是关于如何在 WHERE 子句中使用临时列名?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL 的 WHERE 子句中动态调用列

变量作为 Oracle PL/SQL 中 where 子句中的列名

如何使用数千个 WHERE 子句优化 SQL 查询

在 where 子句中执行 Oracle 查询

[MySQL] 过滤数据

如何在 EXECUTE IMMEDIATE 中使用动态 where 子句