在 oracle sql 中进行数据透视时出现无效标识符错误

Invalid identifier error when pivot in oracle sql

我正在尝试从 order_tbl 调整销售额(即数量*价格),但得到

"ORA-00904: "Sales" invalid identifiers".

任何人都可以帮助解决以下问题 sql 有什么问题吗?

SELECT order_pay, product_id, (quantity * price) as sales
          FROM order_tbl
       PIVOT (SUM (sales) FOR order_pay IN ('01-MAY-2015', '02-MAY-2015'))

创建 table 和插入数据的脚本如下。

CREATE TABLE ORDER_TBL
(
  ORDER_PAY   DATE,
  ORDER_ID    VARCHAR2(10 BYTE),
  PRODUCT_ID  VARCHAR2(10 BYTE),
  QUANTITY    NUMBER(5),
  PRICE       NUMBER(5)
)
Insert into ORDER_TBL
   (ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
 Values
   (TO_DATE('5/1/2015', 'MM/DD/YYYY'), 'ORD1', 'PROD1', 5, 5);
Insert into ORDER_TBL
   (ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
 Values
   (TO_DATE('5/1/2015', 'MM/DD/YYYY'), 'ORD2', 'PROD2', 2, 10);
Insert into ORDER_TBL
   (ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
 Values
   (TO_DATE('5/1/2015', 'MM/DD/YYYY'), 'ORD3', 'PROD3', 10, 25);
Insert into ORDER_TBL
   (ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
 Values
   (TO_DATE('5/1/2015', 'MM/DD/YYYY'), 'ORD4', 'PROD1', 20, 5);
Insert into ORDER_TBL
   (ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
 Values
   (TO_DATE('5/2/2015', 'MM/DD/YYYY'), 'ORD5', 'PROD3', 5, 25);
Insert into ORDER_TBL
   (ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
 Values
   (TO_DATE('5/2/2015', 'MM/DD/YYYY'), 'ORD7', 'PROD1', 2, 5);
Insert into ORDER_TBL
   (ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
 Values
   (TO_DATE('5/2/2015', 'MM/DD/YYYY'), 'ORD8', 'PROD5', 1, 50);
Insert into ORDER_TBL
   (ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
 Values
   (TO_DATE('5/2/2015', 'MM/DD/YYYY'), 'ORD9', 'PROD6', 2, 50);
Insert into ORDER_TBL
   (ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
 Values
   (TO_DATE('5/2/2015', 'MM/DD/YYYY'), 'ORD10', 'PROD2', 4, 10);
Insert into ORDER_TBL
   (ORDER_PAY, ORDER_ID, PRODUCT_ID, QUANTITY, PRICE)
 Values
   (TO_DATE('5/2/2015', 'MM/DD/YYYY'), 'ORD6', 'PROD4', 6, 20);
COMMIT;

不能在同一级别的查询中使用列别名,因此 sales 不会被识别为数据透视子句中的标识符。它也不会识别您当前查询的 pricequantity,因为它们不在被旋转的投影中,因为计算 sales 在那里 - 这似乎有点矛盾。

如评论中所述,您可以更改查询以直接在数据透视子句中进行聚合(这样您就不会将 sales 计算为单独的值,并在初始值中获取两个基列select 列表),但这也不起作用,除非您使用内联视图:

SELECT *
FROM (
  SELECT order_pay, product_id, quantity, price
  FROM order_tbl
)
PIVOT (SUM (quantity * price) FOR order_pay IN ('01-MAY-2015', '02-MAY-2015'))

db<>fiddle.

如果您特别希望能够在数据透视子句中引用 sales,那么您可以在内联视图中进行 sales 计算:

SELECT *
FROM (
  SELECT order_pay, product_id, (quantity * price) as sales
  FROM order_tbl
)
PIVOT (SUM (sales) FOR order_pay IN ('01-MAY-2015', '02-MAY-2015'))

但是 '01-MAY-2015' 是一个字符串,而不是日期,所以你依赖于隐式转换和 NLS 设置;最好使用日期文字:

SELECT *
FROM (
  SELECT order_pay, product_id, (quantity * price) as sales
  FROM order_tbl
)
PIVOT (SUM (sales) FOR order_pay IN (DATE '2015-05-01', DATE '2015-05-02'))

当然,您也可以在数据透视子句中为数据透视列指定更友好的别名,并对结果进行排序,以获得如下内容:

PRODUCT_ID May01 May02
PROD1 125 10
PROD2 20 40
PROD3 250 125
PROD4 null 120
PROD5 null 50
PROD6 null 100

db<>fiddle