sql - 使用分组和聚合函数
问题描述
我对 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 子句,但它使所有内容都以一种逻辑倒退的方式进行。我是唯一有问题的人吗?...离奇:(
解决方案
它肯定是重复的,因此是不可取的,但很难避免重复。您可以使用嵌套查询:
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 子句推送到内部查询中,但我不想保证它确实如此(并且不同的系统可能会以不同的方式处理它)。
推荐阅读
- php - 如何使用 PHP 为具有相同分数的用户分配相同的排名?
- javascript - 在vue js中更改浏览器返回事件
- excel - 打开文件 Workbooks.Open(Filepath) 时出现错误 91
- java-8 - 如果一个列表的元素以另一个列表的元素开头,则返回 true 或 false
- tensorflow - TensorFlow 2:StringLookUp 或 categorical_column_with_vocabulary_list
- awk - 使用一组特定列的 awk 或 sed 更改字段分隔符
- azure - 我从 Azure 通用工件下载了工件,但下载的是哪个路径
- html - 环绕上方的 div,而中心 div 留在中间
- javascript - 在反应谷歌地图上定位侧导航
- r - 删除特定时间段内出现的重复项