首页 > 技术文章 > SQL分组

liuguangshou123 2020-10-31 15:58 原文

建立分组:

vend_id是Vendor_id的缩写:供应商id,products是一个存储商品信息的表。

通过GROUP BY语句,我们可以按照供应商分组,然后组内计数

SELECT a.prod_id,a.prod_name,a.prod_price,a.prod_desc,b.num_prods
FROM products a
join 
(
SELECT vend_id,count(*) as num_prods
FROM products
group by vend_id
) b
on a.vend_id=b.vend_id
where num_prods>2

查询提供2个以上产品的供应商的产品。

 GROUP BY的一些重要规定:

1,GROUP BY子句可以包含任意数目的列,如果在GROUP BY子句中嵌套了分组,数据将GROUP BY会在最后指定的分组上进行行汇总。

SELECT vend_id,prod_id,COUNT(*) AS num_prods
FROM products
GROUP BY vend_id,prod_id;

结果:

2,GROUP BY中的每一列必须是检索列或者表达式。

相似问题可以查看,https://blog.csdn.net/weixin_43495390/article/details/103372662

GROUPBY不能使用别名的原因是它在select语句前执行。所以这就引出第3点

3,GROUP BY子句必须出现在WHERE子句后,ORDER BY子句之前。

4,如果分组列中包含NULL值的行,那么NULL也会作为一个分组返回。

 过滤分组:

你可能想要列出至少有两个订单的所有顾客。为此必须要基于组过滤,而不是个别的行进行过滤。

尽管有WHERE子句,但这个任务中WHERE不能完成任务,因为WHERE过滤的是行不是组。

那么怎么过滤分组呢?请看以下例子:

这段代码在最后一行增加了HAVING,它的作用就是过滤掉COUNT(*)>=2的那些分组。

SELECT order_date,cust_id,count(*) as orders from orders
where date_format(order_date,'%Y%m')<=201202
group by cust_id
having count(*)>=1

进一步练习,如果想要返回在2012年2月之前的,具有两个以上订单的顾客。就要增加一条WHERE子句

分组和排序


Order By 和 GROUP BY的差别

差别在于GROUPBY分组的数据并不总是以分组顺序输出,因为这不是sql规范要求的。

即便DBMS总是按分组顺序输出,用户可能会要求以不同的顺序排序。

所以使用group by子句时,应该给出order by子句。不要仅依赖GROUP BY 排序数据。

举例:输入

SELECT order_num,count(*) as items from orderitems
GROUP BY order_num
HAVING count(*)>=3

输出:

没经过order by排序后。

加入items后

SELECT order_num,count(*) as items from orderitems
GROUP BY order_num
HAVING count(*)>=3
order by items;

输出:

 

 加入order_num后:

 行按order_num排序

 

推荐阅读