>>与软件开发有关的知识:操作系统,数据库,网络通信等 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 20681 个阅读者 刷新本主题
 * 贴子主题:  SQL查询语句的分组和排序 回复文章 点赞(0)  收藏  
作者:flybird    发表时间:2020-01-28 13:17:55     消息  查看  搜索  好友  邮件  复制  引用

                          

数据分组

目前为止的所有计算都是在表的所有数据或匹配特定的 WHERE 子句的数据上进行的。提示一下,下面的例子返回供应商 1003 提供的产品数目

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

但如果要返回每个供应商提供的产品数目怎么办?或者返回只提供单项产品的供应商所提供的产品,或返回提供10个以上产品的供应商怎么办?

这就是分组显身手的时候了。分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算

创建分组

分组是在 SELECT 语句的 GROUP BY 子句中建立的。理解分组的最好办法是看一个例子

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

上面的 SELECT 语句指定了两个列, vend_id 包含产品供应商的ID,

num_prods 为计算字段(用 COUNT(*) 函数建立)。 GROUP BY 子句指示MySQL按 vend_id 排序并分组数据。这导致对每个 vend_id 而不是整个表

计算 num_prods 一次。从输出中可以看到,供应商 1001 有 3 个产品,供应商1002 有 2 个产品,供应商 1003 有 7 个产品,而供应商 1005 有 2 个产品

     因为使用了 GROUP BY ,就不必指定要计算和估值的每个组了。系统会自动完成。 GROUP BY 子句指示MySQL分组数据,然后对每个组而不是整个结果集进行聚集

     在具体使用 GROUP BY 子句前,需要知道一些重要的规定。
  • GROUP BY 子句可以包含任意数目的列。这使得能对分组进行嵌套,

    为数据分组提供更细致的控制。
  • 如果在 GROUP BY 子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算

    (所以不能从个别的列取回数据)。
  • GROUP BY 子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在 SELECT 中使用表达式,则必须在GROUP BY 子句中指定相同的表达式。不能使用别名。
  • 除聚集计算语句外, SELECT 语句中的每个列都必须在 GROUP BY 子句中给出。
  • 如果分组列中具有 NULL 值,则 NULL 将作为一个分组返回。如果列中有多行 NULL 值,它们将分为一组。
  • GROUP BY 子句必须出现在 WHERE 子句之后, ORDER BY 子句之前。
使用 ROLLUP 使用 WITH ROLLUP 关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值,如下所示

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

过滤分组

除了能用 GROUP BY 分组数据外,MySQL还允许过滤分组,规定包括哪些分组,排除哪些分组。例如,可能想要列出至少有两个订单的所有顾客。为得出这种数据,必须基于完整的分组而不是个别的行进行过滤

     HAVING 非常类似于 WHERE 。事实上,目前为止所学过的所有类型的 WHERE 子句都可以用 HAVING 来替代。唯一的差别是WHERE 过滤行,而 HAVING 过滤分组

     HAVING 支持所有 WHERE 操作符,我们学习了 WHERE 子句的条件(包括通配符条件和带多个操作符的子句)。所学过的有关 WHERE 的所有这些技术和选项都适用于HAVING 。它们的句法是相同的,只是关键字有差别

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

     这条 SELECT 语句的前3行类似于上面的语句。最后一行增加了HAVING 子句,它过滤 COUNT(*) >=2 (两个以上的订单)的那些分组。

正如所见,这里 WHERE 子句不起作用,因为过滤是基于分组聚集值而不是特定行值的

     HAVING 和 WHERE 的差别 这里有另一种理解方法, WHERE 在数据分组前进行过滤, HAVING 在数据分组后进行过滤。这是一个重要的区别, WHERE 排除的行不包括在分组中。这可能会改变计

算值,从而影响 HAVING 子句中基于这些值过滤掉的分组

     那么,有没有在一条语句中同时使用 WHERE 和 HAVING 子句的需要呢?

事实上,确实有。假如想进一步过滤上面的语句,使它返回过去12个月内具有两个以上订单的顾客。为达到这一点,可增加一条 WHERE 子句,过滤出过去12个月内下过的订单。然后再增加 HAVING 子句过滤出具有两个以上订单的分组

为更好地理解,请看下面的例子,它列出具有 2 个(含)以上、价格为 10 (含)以上的产品的供应商

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

分组和排序

虽然 GROUP BY 和 ORDER BY 经常完成相同的工作,但它们是非常不同的。下表汇总了它们之间的差别

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

     上表中列出的第一项差别极为重要。我们经常发现用 GROUP BY 分组的数据确实是以分组顺序输出的。但情况并不总是这样,它并不是SQL规范所要求的。此外,用户也可能会要求以不同于分组的顺序排序。仅因为你以某种方式分组数据(获得特定的分组聚集值),并不表示你需要以相同的方式排序输出。应该提供明确的 ORDER BY 子句,即使其效果等同于 GROUP BY 子句也是如此

     不要忘记 ORDER BY 一般在使用 GROUP BY 子句时,应该也给出 ORDER BY 子句。这是保证数据正确排序的唯一方法。千万不要仅依赖 GROUP BY 排序数据

     检索总计订单价格大于等于 50 的订单的订单号和总计订单价格

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

SELECT子句顺序

下面回顾一下 SELECT 语句中子句的顺序。下表以在 SELECT 语句中使用时必须遵循的次序,列出迄今为止所学过的子句

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

     我们学习了如何用SQL聚集函数对数据进行汇总计算。

本文讲授了如何使用 GROUP BY 子句对数据组进行这些汇总计算,返回每个组的结果。我们看到了如何使用 HAVING 子句过滤特定的组,还知道了ORDER BY 和 GROUP BY 之间以及 WHERE 和 HAVING 之间的差异。

        
----------------------------
原文链接:https://www.cnblogs.com/ygjzs/p/12230270.html

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-01-29 17:46:45 重新编辑]
网站系统异常


系统异常信息
Request URL: http://www.javathinker.net/WEB-INF/lybbs/jsp/topic.jsp?postID=1688&replyID=0&skin=1&saveSkin=true&pages=1&replyNum=

java.lang.NullPointerException

如果你不知道错误发生的原因,请把上面完整的信息提交给本站管理人员