oracle SQL无法识别where子句中的列别名[重复]

fjaof16o  于 2023-05-16  发布在  Oracle
关注(0)|答案(3)|浏览(263)

此问题已在此处有答案

Using an Alias in a WHERE clause(5个答案)
11个月前关闭。
SQL在此脚本的WHERE子句中遇到问题:

SELECT
  ITEM_ID, ITEM_PRICE, DISCOUNT_AMOUNT, QUANTITY, 
  (ITEM_PRICE*QUANTITY) AS price_total, 
  (DISCOUNT_AMOUNT*QUANTITY) AS discount_total, 
  ((ITEM_PRICE-DISCOUNT_AMOUNT)*QUANTITY) AS item_total
FROM ORDER_ITEMS
WHERE item_total > 500
ORDER BY item_total;

我收到这个错误:

Error starting at line : 1 in command -
SELECT 
  ITEM_ID, ITEM_PRICE, DISCOUNT_AMOUNT, QUANTITY,  
  (ITEM_PRICE*QUANTITY) AS price_total,  
  (DISCOUNT_AMOUNT*QUANTITY) AS discount_total,  
  ((ITEM_PRICE-DISCOUNT_AMOUNT)*QUANTITY) AS item_total 
FROM ORDER_ITEMS 
WHERE item_total > 500 
ORDER BY item_total DESC;
Error at Command Line : 7 Column : 7
Error report -
SQL Error: ORA-00904: "ITEM_TOTAL": invalid identifier
00904. 00000 -  "%s: invalid identifier"
*Cause:    
*Action:

为什么price_total和discount_total都没有问题,但是报告item_total无效?
我试图首先选择只有项目有一个总大于500时,折扣金额减去,它是乘以数量。然后,我需要按item_total的降序对结果进行排序。

mbjcgjjk

mbjcgjjk1#

别名可以在查询选择列表中使用,以便为列指定不同的名称。您可以在GROUP BY、ORDER BY或HAVING子句中使用别名来引用列。
标准SQL不允许在WHERE子句中引用列别名。施加此限制是因为在计算WHERE子句时,可能尚未确定列值。

因此,以下查询是非法的:

SQL> SELECT empno AS employee, deptno AS department, sal AS salary
  2  FROM emp
  3  WHERE employee = 7369;
WHERE employee = 7369
      *
ERROR at line 3:
ORA-00904: "EMPLOYEE": invalid identifier

SQL>

列别名允许用于:

*分组依据
*订购方式
*拥有

在以下情况下,可以在WHERE子句中引用列别名:
1.子查询
1.公共表表达式(CTE)
比如说

SQL> SELECT * FROM
  2  (
  3  SELECT empno AS employee, deptno AS department, sal AS salary
  4  FROM emp
  5  )
  6  WHERE employee = 7369;

  EMPLOYEE DEPARTMENT     SALARY
---------- ---------- ----------
      7369         20        800

SQL> WITH DATA AS(
  2  SELECT empno AS employee, deptno AS department, sal AS salary
  3  FROM emp
  4  )
  5  SELECT * FROM DATA
  6  WHERE employee = 7369;

  EMPLOYEE DEPARTMENT     SALARY
---------- ---------- ----------
      7369         20        800

SQL>
e1xvtsh3

e1xvtsh32#

从Oracle 12c开始,你可以使用CROSS APPLY来定义表达式,然后你可以在WHERE子句中引用它们:

SELECT
  o.ITEM_ID, o.ITEM_PRICE, o.DISCOUNT_AMOUNT, o.QUANTITY, 
  s.price_total, s.discount_total, s.item_total
FROM ORDER_ITEMS o
CROSS APPLY (SELECT ITEM_PRICE*QUANTITY AS price_total, 
                    DISCOUNT_AMOUNT*QUANTITY AS discount_total, 
                  (ITEM_PRICE-DISCOUNT_AMOUNT)*QUANTITY AS item_total FROM dual) s
WHERE s.item_total > 500
ORDER BY s.item_total;
jxct1oxe

jxct1oxe3#

不能使用在查询中用作别名的列名
原因:
查询将首先检查运行时,在表“ORDER_ITEMS”中找不到列名“item_total”,因为它是作为别名给予的,而别名未存储在任何地方,并且您仅在所需输出中分配该列
候补:
如果你想使用这种类型的子查询,它的性能不是很好,但它是一种替代方法

SELECT * FROM
 (SELECT
  ITEM_ID, ITEM_PRICE, DISCOUNT_AMOUNT, QUANTITY, 
  (ITEM_PRICE*QUANTITY) AS price_total, 
  (DISCOUNT_AMOUNT*QUANTITY) AS discount_total, 
  ((ITEM_PRICE-DISCOUNT_AMOUNT)*QUANTITY) AS item_total
 FROM ORDER_ITEMS) as  tbl
WHERE tbl.item_total > 500
ORDER BY tbl.item_total;

相关问题