为什么不创建此功能?

问题描述 投票:0回答:2

[试图创建一个需要一个月(1-12)并返回具有最高销售额(qtyordered *报价)的productID的函数。错误:PL / SQL:ORA-00936:缺少表达式,来自where子句中的子查询。我假设这是此函数的唯一错误,但我似乎无法使此子查询正常工作。

SQL的新功能,如果这太明显了,我深表歉意。使用Oracle。

CREATE OR REPLACE FUNCTION get_monthly_sales (month_num IN NUMBER)
RETURN NUMBER IS 
    p_id NUMBER(10,0) := 0;
BEGIN 
    SELECT productid INTO p_id
    FROM order_details ods INNER JOIN orders o
        ON ods.orderid = o.id
    WHERE (SELECT MAX(SUM(qtyordered * quotedprice)) FROM order_details)
    AND EXTRACT(MONTH FROM orderdate) = month_num;
RETURN p_id;
END;

编辑:我将IN关键字添加到WHERE子句中,该子句允许创建函数,但现在返回以下错误:ORA-00978:没有GROUP BY的嵌套组函数。

WHERE p_id IS 
        (SELECT MAX(SUM(qtyordered * quotedprice)) FROM order_details)
    AND EXTRACT(MONTH FROM orderdate) = month_num;
sql oracle group-by sql-function
2个回答
0
投票

尝试此

  Select productid INTO p_id 
    from(SELECT productid 

   FROM order_details ods INNER JOIN 
    orders o
    ON ods.orderid = o.id

 WHERE 
EXTRACT(MONTH FROM orderdate) 
= month_num 
order by (qtyordered * quotedprice)
Desc) where rownum=1

0
投票

您是正确的,您的问题出在WHERE子句中。但是,我不知道您要做什么,因此很难为您提供建议。

您有

WHERE (SELECT MAX(SUM(qtyordered * quotedprice)) FROM order_details) ...

问题是,(SELECT MAX(SUM(qtyordered * quotedprice)) FROM order_details)不是布尔表达式-它不能独立存在于WHERE子句中。此外,使用SUM函数意味着您正在尝试对某些内容进行分组,因为SUM(如下所示)是分组函数-但是您的子查询中没有GROUP BY表达式,拥有一个似乎也没有多大意义。

[此外,我不确定您是否真的要传递MONTH_NUM作为参数,并按原样使用它。假设您传入4作为MONTH_NUM,表示“ 4月”。您编写函数的方式(假设查询有效),您将收集2018年4月,2019年4月,2020年4月等的数据,等等。我怀疑您是否想要这样做。也许您想传递一个日期,然后将其截断到月份级别。所以也许您在寻找

CREATE OR REPLACE FUNCTION GET_MONTHLY_SALES(pin_Month IN DATE)
  RETURN NUMBER
IS
  nTotal_monthly_sales  NUMBER; 
BEGIN 
  SELECT SUM(od.QTYORDERED * od.QUOTEDPRICE)
    INTO nTotal_monthly_sales
    FROM ORDER_DETAILS od
    INNER JOIN ORDERS o
      ON o.ID = od.ORDERID
    WHERE TRUNC(o.ORDERDATE, 'MONTH') = TRUNC(pin_Month, 'MONTH');

  RETURN nTotal_monthly_sales;
END GET_MONTHLY_SALES;

(这应该(如果我已经猜到了各个字段正确显示在哪些表上的话)应该为您提供与输入日期相对应的月份的总销售额,这似乎与函数名称相对应。

编辑

根据您对问题的描述,解决方案应该类似于

CREATE OR REPLACE FUNCTION FIND_PRODUCT_WITH_MAX_SALES(pinMonth IN NUMBER)
  RETURN NUMBER
IS
BEGIN
  IF pinMonth BETWEEN 1 AND 12 THEN
    FOR aRow IN (SELECT od.PRODUCT_ID,
                        SUM(od.QTYORDERED * od.QUOTEDPRICE) AS TOTAL_MONTHLY_SALES
                   FROM ORDER_DETAILS od
                   INNER JOIN ORDERS o
                     ON o.ID = od.ORDERID
                   WHERE TO_NUMBER(TO_CHAR(o.ORDERDATE, 'MM')) = pinMonth
                   GROUP BY od.PRODUCT_ID
                   ORDER BY SUM(od.QTYORDERED * od.QUOTEDPRICE) DESC)
    LOOP
      RETURN aRow.TOTAL_MONTHLY_SALES;
    END LOOP;
  ELSE
    RAISE_APPLICATION_ERROR(-20001, 'FIND_PRODUCT_WITH_MAX_SALES: Error - pinMonth (' || 
                                    pinMonth || ') not in range 1..12'); 
  END IF;
END FIND_PRODUCT_WITH_MAX_SALES;
© www.soinside.com 2019 - 2024. All rights reserved.