【问题标题】:Invalid identifier error when pivot in oracle sql在 oracle sql 中透视时出现无效标识符错误
【发布时间】:2021-10-13 07:32:27
【问题描述】:

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

“ORA-00904:“销售”无效标识符”。

谁能帮忙看看下面的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'))

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

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;

【问题讨论】:

  • PIVOT (SUM (quantity * price) FOR.... 而不是 PIVOT (SUM (sales) FOR....
  • pivot 操作在select 步骤之前 执行,您希望执行引擎如何知道sales 的含义?正如 Igor 在上面的评论中所说,将 pivot 中的聚合更改为 sum(quantity * price)。但还要注意,输出中不会有 sales 列;在pivotin 子句中,您将有两个日期的列。除了您已经与我们分享的内容之外,如果您能显示您的确切预期输出,将会有所帮助。

标签: sql oracle pivot


【解决方案1】:

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

如 cmets 中所述,您可以将查询更改为直接在 pivot 子句中进行聚合(因此您不会将 sales 计算为单独的值,并在初始选择列表中获取两个基本列),但这也不起作用,除非您使用内联视图:

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.

如果您特别希望能够在 pivot 子句中引用 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

【讨论】:

  • “无法识别quantityprice”是什么意思?如果您从基表中选择quantityprice 到内联视图中(而不是在那里执行乘法),它们pivot 中被识别。如果您确实需要一个内联视图(就像您可能需要的那样,忽略旋转中的 order_id 列 - 尽管我们并不真正知道所需的输出是什么!),那么在内联视图中执行乘法是有意义的,但是这是一个选择,而不是一个要求。
  • 是的,但是 OP 正在 在那里执行乘法 - (quantity * price) as sales。当然,获得单独的列也很好。但是,您也不只是“更改枢轴中的聚合”
  • 如果您在最后引用的片段中引用了我对 OP 的评论,请同时阅读我在那之后立即写的内容 - 不要断章取义。
  • 如果您在内联视图中选择数量和价格,并在枢轴中汇总他们的产品,那么任何地方都会有 no 称为“销售”的数量 - 而不是在内联视图中,当然不在输出中。
  • 我确实看过下面这句话,似乎没有关系。无论哪种方式,输出中都没有“销售”。如果您的意思是在初始选择列表中没有计算销售额,那么这对我来说不是这样。 (而且,实际上,it doesn't work 无论如何都会在总和中进行计算......我本以为会这样。)
猜你喜欢
  • 2017-04-18
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多