首页 > 解决方案 > 使用分组和聚合函数

问题描述

我对 SQL 并不陌生,但由于缺少一些知识,我觉得我从未完全理解 SQL。我们都知道在使用group by的时候需要用到聚合函数,比如我们有一个orderdetails表(orderid和productid的组合键),写一个查询返回总价值(数量*单价)大于10000的订单,sql为:

select orderid, sum(qty*unitprice) AS totalvalue from Sales.OrderDetails
group by orderid
having sum(qty*unitprice) > 10000

正如我们所知,选择发生在分组和拥有之后,所以当我来到

group by orderid
having sum(qty*unitprice) > 10000

我们已经按 orderid 对所有记录进行了分组,并总结了所有成本,如果我们可以想象成:

orderid  null(a column with no name but contains the total value)

123456   11000.00
987654   12184.00

然后是选择子句:

select orderid, sum(qty*unitprice) AS totalvalue

因为我们已经在 'have' 子句之后得到了结果,所以为什么我们需要做 'sum(qty*unitprice)' 来再次进行求和,这不是多余的吗?

还有一个让我很困扰的是:在写SQL的时候,select子句在from子句之前,很不方便,因为要获取列名的IntelliSense。当然,我可以先从 caluse 开始编写,然后“插入” select 子句,但它使所有内容都以一种逻辑倒退的方式进行。我是唯一有问题的人吗?...离奇:(

标签: sql

解决方案


它肯定是重复的,因此是不可取的,但很难避免重复。您可以使用嵌套查询:

SELECT orderid, totalvalue
  FROM (SELECT orderid, SUM(qty * unitprice) AS totalvalue
          FROM sales.orderdetails
         GROUP BY orderid) AS order_value
 WHERE totalvalue > 10000

您需要查看 DBMS 的优化器计划,以确定这样做是否会导致显着的性能损失,但它避免了重复SUM(qty * price)表达式。理想情况下,优化器会将外部 WHERE 子句作为 HAVING 子句推送到内部查询中,但我不想保证它确实如此(并且不同的系统可能会以不同的方式处理它)。


推荐阅读