mysql的分组和过滤桶where的组合运用

理解分组,可以这样:对GROUP BY子句后面跟随的列名进行分组,然后对每一个分组而不是整个表进行操作。

举例:在产品表中,检索每一个供应商提供的商品的数量。

mysql> SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id;
结果:
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
|    1001 |         3 |
|    1002 |         2 |
|    1003 |         7 |
|    1005 |         2 |
+---------+-----------+
4 rows in set (0.01 sec)

分析:

首先根据vend_id进行分组,然后对每一个分组在进行COUNT聚集。当检索的目的是针对每一个记录进行检索的时候,想到用GROUP BY,例如这里是针对每一个供应商。

GROUP BY的规定:

1、GROUP BY 后面可以包含多个列,这就是嵌套。

2、如果GROUP BY进行了嵌套,数据将在最后一个分组上进行汇总。

3、GROUP BY子句中列出来的每个列必须是检索列或有效的表达式(但不能是聚集函数),如果在SELECT中使用了表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名。

4、除了聚集语句外,SELECT语句中的每一个列都必须在GROUP BY子句中给出。

5、如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多个NULL,它们将作为一个分组返回。

6、GROUP BY子句必须在WHERE 子句之后,ORDER BY 子句之前。

过滤分组结果

我们知道WHERE 子句用于过滤结果,但是对于分组的过滤WHERE子句不行。

因为WHERE子句,是针对行的过滤。要对分组结果进行过滤,必须使用HAVING子句,HAVING子句能针对分组的结果进行过滤。

举例:

在订单表中,检索出具有两个以上订单的客户id以及订单数量。

分析:

在这个检索需求中,需要先根据客户id进行分组,然后过滤出订单数量大于2的分组。

mysql> SELECT cust_id,COUNT(*) AS orders FROM orders GROUP BY cust_id HAVING orders>=2;

  

结果:
+---------+--------+
| cust_id | orders |
+---------+--------+
|   10001 |      2 |
+---------+--------+
1 row in set (0.00 sec)

与WHERE组合使用(先用WHERE过滤)

有的时候,GROUP BY和WHERE子句也要组合使用。比如:在产品表中检索出能提供2个以上商品,并且价格高于10的供应商。

分析:

首先,检索的是供应商,因此SELECT子句应该是SELECT vend_id

其次,产品表中,有价格这一列,因此对于价格高于10的条件的过滤要使用WHERE子句。SELECT vend_id FROM prodcuts WHERE prod_price>=10.

接着,对vend_id进行分组,这样就可以得到每个vend_id的价格高于10的商品数量,GROUP BY放到WHERE子句后。SELECT vend_id FROM prodcuts WHERE prod_price>=10 GROUP BY vend_id.

最后,对分组的结果过滤,过滤出2个以上商品的分组

mysql> SELECT vend_id,COUNT(*) AS num_prods FROM products WHERE prod_price>=10 GROUP BY vend_id HAVING COUNT(*)>=2;
结果:
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
|    1003 |         4 |
|    1005 |         2 |
+---------+-----------+
2 rows in set (0.00 sec)

对分组结果进行排序

在订单明细表中,检索出订单总价格高于等于50的订单号以及订单总价格

mysql> SELECT order_num,SUM(quantity*item_price) AS ordertotal FROM orderitems GROUP BY order_num HAVING SUM(quantity*item_price)>=50 ORDER BY ordertotal;
结果是:
+-----------+------------+
| order_num | ordertotal |
+-----------+------------+
|     20006 |      55.00 |
|     20008 |     125.00 |
|     20005 |     149.87 |
|     20007 |    1000.00 |
+-----------+------------+
4 rows in set (0.08 sec)

  

SELECT 子句的顺序

SELECT

FROM

WHERE

GROUP BY #分组

HAVING #过滤

ORDER BY #

LIMIT #限制

  

原文地址:https://www.cnblogs.com/z18271397173/p/9275826.html

时间: 2024-10-12 10:29:53

mysql的分组和过滤桶where的组合运用的相关文章

mysql实现分组排序

群里有童鞋问,想要根据用户分组,以该用户的下单时间为降序,提取所有用户的第二个订单信息. 这属于分组排序,在Oracle有内置函数可以实现,而在mysql,做起来比较蛋疼. 我提供一种方法供参考 CREATE TABLE user_orders (orders_id INT UNSIGNED NOT NULL, user_id INT UNSIGNED NOT NULL, add_time INT UNSIGNED NOT NULL, PRIMARY KEY(orders_id), KEY(us

mysql查询分组之后获取结果集总数

相信分页查询对于很多开发者来说都是司空见惯的事情,首先按照查询条件搜索出分页列表数据和总的记录数,获取总的记录数一般是: select count(1) as total from xxx where .......... 这没有问题,但是如果查询的条件有分组group by 那这个时候获取总数就有问题了,这样是获取每个分组的总数 解决办法: select count(1) as total from ( select id from xxx where .... grouy by .....)

Mysql 数据分组取某字段值所有最大的记录行

需求: 表中同一个uid(用户)拥有多条游戏等级记录,现需要取所有用户最高等级(level)的那一条数据,且时间(time)越早排越前.这是典型的排名表 +------+-------+--------------+---------------------+ | uid | level | role | time | +------+-------+--------------+---------------------+ | 7 | 1 | 摇滚圣魔 | 2014-06-12 15:01:0

MySQL 对分组后的同类数据进行拼接字符串

MySQL 对分组后的同类数据进行拼接字符串 写后台方法时遇到个问题,需要将表内同一订单号的操作记录流水进行简单拼接输出,不想取出来再操作,找了个mysql的方法直接操作 group_concat对组内的每一行数据拼接,内部可以排序.使用separator 进行分割 concat_ws对一行内的各个字段进行拼接,第一项指定分隔符,后续的有null会忽略 select oid, group_concat(concat_ws('|',atime,(select `level` from prizes

MySQL高级分组排序

想要根据用户分组,以该用户的下单时间为降序,提取所有用户的第二个订单信息.这属于分组排序,在Oracle有内置函数可以实现,而在mysql就有点麻烦: CREATE TABLE user_orders (orders_id INT UNSIGNED NOT NULL, user_id INT UNSIGNED NOT NULL, add_time INT UNSIGNED NOT NULL, PRIMARY KEY(orders_id), KEY(user_id), KEY(add_time)

MySQL时间分组查询

表TESTER 字段:id -- INT    date  -- TIMESTAMP 1.如何按年.月.日分组查询? select DATE_FORMAT(date,'%Y-%m-%d') time, count(*) count from TESTER group by year(date), month(date), day(date); 其中year().month().day()分别是提取date中的年.月.日字段. 2.时间分组查询的效率? 在不建立索引时,我100W行数据进行测试,用

SQL语句汇总(三)——聚合函数、分组、子查询及组合查询 - Darly

–COUNT:统计行数量 –SUM:获取单个列的合计值 –AVG:计算某个列的平均值 –MAX:计算列的最大值 –MIN:计算列的最小值 首先,创建数据表如下: 执行列.行计数(count): 标准格式 SELECT COUNT(<计数规范>) FROM <表名> 其中,计数规范包括: - * :计数所有选择的行,包括NULL值: - ALL 列名:计数指定列的所有非空值行,如果不写,默认为ALL: - DISTINCT 列名:计数指定列的唯一非空值行. 例,计算班里共有多少学生:

MySQL获取分组后的TOP 1和TOP N记录

有时会碰到一些需求,查询分组后的最大值,最小值所在的整行记录或者分组后的top n行的记录,在一些别的数据库可能有窗口函数可以方面的查出来,但是MySQL没有这些函数,没有直接的方法可以查出来,可通过以下的方法来查询. 准备工作 测试表结构如下: root:test> show create table test1\G *************************** 1. row *************************** Table: test1 Create Table:

mysql下分组取关联表指定提示方法,类似于mssql中的cross apply

转至:https://stackoverflow.com/questions/12113699/get-top-n-records-for-each-group-of-grouped-results 通过分组的排序及序号获取条数信息,可以使用到索引,没测试性能,不知道和mssql的cross apply性能差异性为多少,只是能实现相应的效果. 1 #MySQL 5.7.12 2 #please drop objects you've created at the end of the scrip