(六)数据库 | 分组查询与组合查询
发布于 2021-09-08 11:29
分组查询 GROUP BY
组合查询UNION[ALL]
引言
数据检索是SQL中最常用也最复杂的数据操作之一,在数据库系列(三)中,我们讲述了用比较操作符、逻辑操作符和算术操作符构建最简单、最基本的检索条件,这期我们将介绍数据的分组过滤和组合查询!
分组查询
分组(GROUP BY)在日常生活中十分常见,体测时按照性别对测试者进行分组以匹配合适的检测项目,高考时按照省份对考生进行分组以匹配合适的高考试卷,在SELECT语句中利用GROUP BY和HAVING子句进行排序分组和过滤分组;
将一个表中的数据进行分组相当于将该表拆分成多个子表,例如求取每个供应商所提供的产品总数时,可以将产品先按照供应商进行分组,分组后相当于每张产品子表中的供应商相同,然后再分别进行计数即可。
查询每个供应商所提供的产品数目:
SELECT vend_id, COUNT(*) AS num_items
FROM products
GROUP BY vend_id;
特别注意
1、GROUP BY 子句必须出现在FROM子句之后,ORDERY BY子句之前;
2、如果指定的分组列中包含NULL值,则将NULL作为一个分组返回;
3、除聚集函数外,SELECT 语句中的所有列都必须在GROUP BY子句中给出!
4、GROUP BY子句中的所有列必须是自然列或自然列的有效表达式,但不能是聚集函数,若在SELECT中使用了表达式,则GROUP BY子句中也必须包含该表达式
5、GROUP BY子句可以包含任意数目的列(如对于student表指定grade, class和gender三个列作为分组列),即可以建立嵌套分组,嵌套分组指定的所有列一起计算(即只有grade, class和gender都相同时才被归为同一组)。
过滤分组
如果我们想让返回结果中仅含供应产品数大于2的供应商怎么办呢?我们知道,WHERE子句可以通过指定检索条件来过滤行,在分组查询中的HAVING子句也可以通过指定检索条件来过滤分好的组,并且WHERE子句和HAVING子句的检索条件的构建语法是完全一样的,但过滤分组往往需要利用聚集函数来构建过滤条件。
查询订单在两单以上的客户ID:
SELECT cust_id, COUNT(*)
FROM orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;
特别注意
1、在同时使用WHERE和HAVING时,WHERE子句先执行,即先用WHERE子句过滤掉不符合检索条件的行,然后再在剩下的行组成的表中进行分组;
2、GROUP BY子句在进行分组时往往按照一定的顺序并返回分组结果,但这不一定是你所想要的排序结果,所以在需要对分组结果排序时,不能遗漏ORDER BY;
请看例子,查询05年9月份订单总价大于等于50美元的订单号及订单总价格:
SELECT order_num, SUM(quantity*item_price) AS ordertotal
这里首先使用WHERE子句和子查询或联结查询检索出05年9月份的订单,然后用GROUP BY按照订单号分组并统计每个订单的总价格,并用HAVING子句过滤到总价低于50美元的订单,最后用ORDER BY对检索结果按照订单号进行排序以完成查询任务。
组合查询
组合查询:使用UNION关键字组合多条SELECT语句,并将它们的查询结果合并返回成一个结果集。
使用方式:直接将UNION关键字放在两条或多条SELECT语句之间即可,也可以在UNION后使用ALL关键字声明不删除多个查询结果集中出现的重复的行(大多数情况是不需要重复行的,所以默认删除重复行,即一般不使用ALL进行声明)
注意
1、因为在查询时不存在对结果集进行“部分排序“而另一部分不排序的情况,所以ORDERY BY子句仅能使用一次,在组合查询中若要排序则只能在最后一个SELECT语句中使用ORDER BY子句;
2、UNION查询中的每个SELECT查询必须包含相同的列或表达式、聚集函数。
3、UNION组合查询的性能比OR高,当构建检索条件需要使用多个OR时不妨将该查询转换为组合查询,这在查询大量数据的复杂查询中非常有用!
查询商品价格小于等于5或由供应商1001和1002供应的商品
并供应商ID和商品价格升序排列:
SELECT vend_id, prod_id, prod_price
FROM products
WHERE prod_price <= 5
UNION
SELECT vend_id, prod_id, prod_price
FROM products
WHERE vend_id IN (1001, 1002)
ORDER BY vend_id, prod_price;
SELECT vend_id, prod_id, prod_price
FROM products
WHERE prod_price <= 5 OR vend_id IN (1001, 1002)
ORDER BY vend_id, prod_price;
# 似乎所有的组合查询都可以和OR连接的检索互换,但组合查询能够使得负责查询更加简介、容易理解,更重要的是它的速度比OR快!
END
本
期
提
要
分组查询:GROUP BY 分组列名, HAVING 组过滤条件
组合查询:UNION [ALL]
本文来自网络或网友投稿,如有侵犯您的权益,请发邮件至:aisoutu@outlook.com 我们将第一时间删除。
相关素材