ORA-00934:此处不允许使用组功能。 WHERE SUM(x)=(SELECT MIN(SUM(x)))

时间:2019-05-18 11:54:59

标签: sql oracle10g aggregate-functions

需要获得付款金额最小的客户的姓氏和名字。付款有不同的发票付款除以付款方式,因此在确定哪笔付款最小之前,我需要对具有相同发票编号的付款进行总和。付款和客户是由第三个发票连接的不同实体/表。实体之间的关系是一对多的,就像这样:

Client -----<= Invoice ------<= Payment. 

SELECT c.first_name, c.last_name FROM client c, invoice i
wHERE i.id_client_fk1 = c.id_pk
AND i.num_pk = (SELECT num_invoice_fk1 
                FROM payment 
                WHERE SUM(amount_after_tax) = (SELECT MIN(SUM(amount_after_tax)) 
                                               FROM payment 
                                               GROUP BY num_pk));

客户在发票中将PK用作FK,在发票中将PK用作付款FK

我想使用与代码中完全相同的逻辑,但是显然它必须起作用。需要比较WHERE SUM(amount_after_tax) = SELECT MIN(SUM(amount_after_tax))

我知道这不在SQL中(因此是我的问题的标题),但这是我可以提出的逻辑。

 SELECT c.first_name, c.last_name FROM client c, invoice i
 WHERE i.id_client_fk1 = c.id_pk
 AND i.num_pk = (SELECT num_invoice_fk1 FROM payment
                 WHERE amount_after_tax = (SELECT MIN(SUM(amount_after_tax)) 
                 FROM payment
                 GROUP BY num_pk));

此代码在SQL中运行,但是它无法满足我的要求,因为它仅将单个付款与MIN(SUM(amount_after_tax))进行比较。假设我一张发票有3笔付款。我需要对它们进行汇总,以便能够与MIN(SUM(amount_after_tax))进行比较。还尝试使用HAVING,但它不起作用。也许我没有经验。请帮助

Payment Table

Entity Relationship Diagram

2 个答案:

答案 0 :(得分:0)

您应该使用Have过滤汇总结果(而不是在何处)

SELECT c.first_name, c.last_name 
FROM client c, invoice i
WHERE i.id_client_fk1 = c.id_pk
AND i.num_pk = (SELECT
     num_invoice_fk1 
    FROM payment HAVING SUM(amount_after_tax) = 
      (SELECT MIN(amount_after_tax) 
       FROM payment 
       GROUP BY num_pk)
 );

答案 1 :(得分:0)

想到窗口功能

select c.first_name, c.last_name
from client c join
     (select i.id_client_fk1, i.num_pk, sum(p.amount_after_tax) as total_amount,
             row_number() over (order by sum(p.amount_after_tax) asc) as seqnum
      from invoice i join
           payment p
           on p.num_invoice_fk1 = i.num_pk
      group by i.id_client_fk1, i.num_pk
    ) ip
    on i.id_client_fk1 = c.id_pk
where seqnum = 1;

子查询聚合数据并使用row_number()枚举结果。然后,外部查询输入名称并选择第一行。

注意:

  • 从不FROM子句中使用逗号。
  • 始终使用正确的,明确的,标准 JOIN语法。
  • 这里的逻辑很简单。只需合计即可计算出总数,然后取出第一行。

编辑:

因为只需要一行,所以也可以使用rownum

想到窗口功能

select c.first_name, c.last_name
from (select c.first_name, c.last_name,
             i.id_client_fk1, i.num_pk, 
             sum(p.amount_after_tax) as total_amount,
      from invoice i join
           payment p
           on p.num_invoice_fk1 = i.num_pk
           client c join
           on i.id_client_fk1 = c.id_pk
      group by i.id_client_fk1, i.num_pk
      order by total_amount asc
    ) ip
where rownum = 1;