在以下相关子查询中是否需要GROUP BY?

时间:2011-12-27 14:42:03

标签: sql oracle group-by having correlated-subquery

鉴于情景:

table fd  
(cust_id, fd_id) primary-key and amount  

table loan  
(cust_id, l_id) primary-key and amount

我想列出所有定期存款金额低于所有贷款总额的客户。

查询:

SELECT cust_id
  FROM fd
    WHERE amount
     <
    (SELECT sum(amount)
        FROM loan
          WHERE fd.cust_id = loan.cust_id);

OR should we use

SELECT cust_id
  FROM fd
    WHERE amount
     <
    (SELECT sum(amount)
        FROM loan
          WHERE fd.cust_id = loan.cust_id group by cust_id);

客户可以拥有多笔贷款,但一次只能考虑一个FD。

4 个答案:

答案 0 :(得分:4)

在这种情况下,

GROUP BY 可以省略,因为SELECT列表中只有(一个)聚合函数,所有行都保证属于同一组cust_idWHERE子句)。

在两种情况下,聚合将覆盖所有匹配cust_id的行。所以这两个查询都是正确的。


这将是更清洁实现同样事情的另一种方式:

SELECT fd.cust_id
FROM   fd
JOIN   loan USING (cust_id)
GROUP  BY fd.cust_id, fd.amount
HAVING fd.amount < sum(loan.amount)

有一个差异(cust_id, amount)中具有相同fd的行只会在我的查询结果中出现一次,而它们会在原始内容中多次出现。< / p>

无论哪种方式,如果表amount中没有与非空 loan匹配的行,您就会根本没有行 。我假设你知道这一点。

答案 1 :(得分:2)

由于您按GROUP BY过滤了数据,因此无需cust_id。无论如何,内部查询将返回相同的结果。

答案 2 :(得分:2)

不,不是,因为您使用sum(amount)为客户计算id = fd.cust_id,因此对于单个客户。

但是,如果您的子查询以某种方式计算多个客户的总和,group by将导致子查询生成多个行,这将导致条件(&lt;)失败,因此,查询失败。

答案 3 :(得分:1)

使用类似sum但没有group by的聚合的查询将输出一个组。将在所有匹配的行上计算聚合。

条件子句中的子查询只允许返回一行。如果子查询返回多行,则下面的表达式意味着什么?

where 1 > (... subquery ...)

所以必须省略group by;您甚至会在第二次查询时收到错误。

N.B。指定all, any, or some时,子查询可以返回多行:

where 1 > ALL (... subquery ...)

但很容易理解为什么在你的情况下没有意义;您将一个客户的数据与另一个客户的数据进行比较。