【问题标题】:Why is this function not being created?为什么没有创建这个函数?
【发布时间】:2020-04-02 22:29:55
【问题描述】:

尝试创建一个函数,该函数需要一个月(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;

编辑:我在 WHERE 子句中添加了 IN 关键字,这允许创建函数,但现在返回以下错误:ORA-00978:nested group function without 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


    【解决方案1】:

    试试这个

      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
    

    【讨论】:

    • 不。返回:PL/SQL: ORA-01744: inappropriate INTO
    • 仍然没有。 ORA-00937: 不是单组群函数
    【解决方案2】:

    您的问题出在 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,意思是“四月”。您编写函数的方式(假设查询有效)您将收集 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;
    

    【讨论】:

    • 这不是我想要的。这是我的教授提出的确切问题:“创建一个函数(给它一个合适的名称),它接收一个月(作为 1-12 的数字)并返回具有最高销售额(QtyOrdered x QuotedPrice)的产品 ID月份变量”
    猜你喜欢
    • 1970-01-01
    • 2015-06-11
    • 2011-01-06
    • 2013-03-25
    • 1970-01-01
    • 2015-02-08
    • 2019-06-28
    • 1970-01-01
    • 2021-11-06
    相关资源
    最近更新 更多