私はSQLの初心者ですが、この厄介なエラーに遭遇しました。 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の降順で並べ替える必要があります
クエリ選択リストでエイリアスを使用して列に別の名前を付けることができます。GROUPBY、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句で列エイリアスを参照できます。
例えば、
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>
クエリでエイリアスとして使用されている列名は使用できません
理由:
クエリは最初にランタイムをチェックします。このとき、列名「item_total」はテーブル「ORDER_ITEMS」に見つかりません。エイリアスとして指定されているため、どこにも保存されておらず、目的の出力のみにその列を割り当てています。
代わりの:
そのタイプを使用したい場合はサブクエリを使用してください。パフォーマンスは良くありませんが、これは代替方法の1つです
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;
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;