MySQL分组数据和子查询
分组数据
创建分组
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)
- 上面的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子句之前。
- GROUP BY子句可以包含任意数目的列。这使得能对分组进行嵌套,
过滤分组
- HAVING非常类似于WHERE。事实上,目前为止所学过的所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。
mysql> SELECT cust_id,COUNT(*) AS orders
FROM orders
GROUP BY cust_id
HAVING COUNT(*)>=2;
+---------+--------+
| cust_id | orders |
+---------+--------+
| 10001 | 2 |
+---------+--------+
1 row in set (0.00 sec)
- HAVING和WHERE的差别 这里有另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。这是一个重要的区别,WHERE排除的行不包括在分组中。这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组。
分组和排序
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.01 sec)
- 它检索总计订单价格大于等于50的订单的订单号和总计订单价格,按总计订单价格排序输出。
SELECT 子句顺序
| 字句 | 说明 | 是否必须使用 |
|---|---|---|
| SELECT | 要返回的列或表达式 | 是 |
| FORM | 从中检索数据的表 | 仅在从表选择数据时使用 |
| WHERE | 行级过滤 | 否 |
| GROUP BY | 分组说明 | 仅在按组计算聚集时使用 |
| HAVING | 组级过滤 | 否 |
| ORDER BY | 输出排序顺序 | 否 |
| LIMIT | 要检索的行数 | 否 |
子查询
- 子查询就是把一条SELECT语句返回的结果用于另一条SELECT语句的WHERE子句。
利用子查询进行过滤
mysql> SELECT order_num
FROM orderitems
WHERE prod_id='TNT2';
+-----------+
| order_num |
+-----------+
| 20005 |
| 20007 |
+-----------+
2 rows in set (0.01 sec)
mysql> SELECT cust_id
FROM orders
where order_num IN(20005,20007);
+---------+
| cust_id |
+---------+
| 10001 |
| 10004 |
+---------+
2 rows in set (0.00 sec)
mysql> SELECT cust_id
FROM orders
where order_num IN(SELECT order_num
FROM orderitems
WHERE prod_id='TNT2');
+---------+
| cust_id |
+---------+
| 10001 |
| 10004 |
+---------+
2 rows in set (0.01 sec)
- 在SELECT语句中,子查询总是从内向外处理。在处理上面的SELECT语句时,MySQL实际上执行了两个操作。首先,它执行下面的查询:
SELECT order_num FROM orderitems WHERE prod_id='TNT2';
- 此查询返回两个订单号:20005和20007。然后,这两个值以IN操作符要求的逗号分隔的格式传递给外部查询的WHERE子句。外部查询变成:
SELECT cust_id FROM orders where order_num IN(20005,20007);
可以看到,输出是正确的并且与前面硬编码WHERE子句所返回的值相同。
列必须匹配 在WHERE子句中使用子查询(如这里所示),应该保证SELECT语句具有与WHERE子句中相同数目的列。通常,子查询将返回单个列并且与单个列匹配,但如果需要也可以使用多个列。
虽然子查询一般与IN操作符结合使用,但也可以用于测试等于(=)、不等于(<>)等。
作为计算字段使用子查询
mysql> SELECT COUNT(*) AS orders FROM orders WHERE cust_id=10001;
+--------+
| orders |
+--------+
| 2 |
+--------+
1 row in set (0.00 sec)
- 为了对每个客户执行COUNT()计算,应该将COUNT()作为一个子查询。请看下面的代码:
mysql> SELECT cust_name,cust_state,(SELECT COUNT(*)
FROM orders
WHERE orders.cust_id=customers.cust_id) AS orders
FROM customers
ORDER BY cust_name;
+----------------+------------+--------+
| cust_name | cust_state | orders |
+----------------+------------+--------+
| Coyote Inc. | MI | 2 |
| E Fudd | IL | 1 |
| Mouse House | OH | 0 |
| Wascals | IN | 1 |
| Yosemite Place | AZ | 1 |
+----------------+------------+--------+
5 rows in set (0.01 sec)
这 条 SELECT 语句对 customers 表中每个客户返回 3 列 :cust_name、cust_state和orders。orders是一个计算字段,它是由圆括号中的子查询建立的。该子查询对检索出的每个客户执行一次。在此例子中,该子查询执行了5次,因为检索出了5个客户。
子查询中的WHERE子句与前面使用的WHERE子句稍有不同,因为它使用了完全限定列名(在第4章中首次提到)。下面的语句告诉SQL比较orders表中的cust_id与当前正从customers表中检索的cust_id:
WHERE orders.cust_id=customers.cust_id
相关子查询(correlated subquery) 涉及外部查询的子查询。这种类型的子查询称为相关子查询。
MySQL分组数据和子查询的更多相关文章
- MySQL中IN子查询会导致无法使用索引
今天看到一个博客园的一篇关于MySQL的IN子查询优化的案例,一开始感觉有点半信半疑(如果是换做在SQL Server中,这种情况是绝对不可能的,后面会做一个简单的测试.)随后动手按照他说的做了一个表 ...
- MySQL里面的子查询
一.子查询定义 定义: 子查询允许把一个查询嵌套在另一个查询当中. 子查询,又叫内部查询,相对于内部查询,包含内部查询的就称为外部查询. 子查询可以包含普通select可以包括的任何子句,比如:dis ...
- MySQL中in子查询会导致无法使用索引问题(转)
MySQL的测试环境 测试表如下 create table test_table2 ( id int auto_increment primary key, pay_id int, pay_time ...
- 详细讲述MySQL中的子查询操作 (来自脚本之家)
继续做以下的前期准备工作: 新建一个测试数据库TestDB: ? 1 create database TestDB; 创建测试表table1和table2: ? 1 2 3 4 5 6 7 8 9 1 ...
- MySql学习(三) —— 子查询(where、from、exists) 及 连接查询(left join、right join、inner join、union join)
注:该MySql系列博客仅为个人学习笔记. 同样的,使用goods表来练习子查询,表结构如下: 所有数据(cat_id与category.cat_id关联): 类别表: mingoods(连接查询时作 ...
- mysql update from 子查询
mssql 子查询更新 update log set uin= b.uinfrom log a,logs bwhere a.accountuin = b.accountuin mysql 不支持 up ...
- 在MySQL中使用子查询和标量子查询的基本用法
一.MySQL 子查询 子查询是将一个 SELECT 语句的查询结果作为中间结果,供另一个 SQL 语句调用.MySQL 支持 SQL 标准要求的所有子查询格式和操作,也扩展了特有的几种特性.子查询没 ...
- MySql数据库之子查询和高级应用
MySql数据库中的子查询: 子查询:在一条select查询语句中嵌套另一条select语句,其主要作用是充当查询条件或确定数据源. 代码案例如下: 例1. 查询大于平均年龄的学生: select * ...
- mysql 子句、子查询、连接查询
一.mysql查询的五种子句 where子句(条件查询):按照“条件表达式”指定的条件进行查询. group by子句(分组):按照“属性名”指定的字段进行分组.group by子句通常和count( ...
- 数据库之 MySQL --- 数据处理 之 子查询 (二)
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一 .数据库语言定义及命令行查看数据库操作 -- SQL 语言可以分为三类-- DML: 数据操纵语言. ...
随机推荐
- 我的小程序之旅二:如何创建一个微信小程序
第一步.准备邮箱 如果只是个人想体验一下小程序,直接用自己的QQ邮箱就行,但是这样申请的小程序很多权限都是没有的,比如获取用户手机号授权. 如果是企业或服务商要进行开发小程序,那么至少准备三个邮箱,同 ...
- docker 常用命令 快捷命令
一.查询节点 docker ps -a 二.docker重启停止 systemctl restart docker systemctl stop docker docker restart * 三.一 ...
- 关于dpi awareness 的清单文件设置
要设置dpi 意识,一般是使用SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)来设置 具体可参考:Setting the default DP ...
- win32-LPCSTR->String
#include <string> void makebox(LPCSTR name) { std::string res(name); res += " is X"; ...
- 常用JDBC连接池
如下整理常用JDBC连接池组件. HikariCP 针对不同的JDK需要引入对应的HikariCP,详见:Github项目地址 . 以JDK8为例子,在项目中引入如下依赖: <dependenc ...
- FROM_UNIXTIME函数格式化时间戳日期类型
select FROM_UNIXTIME(bce.daysec_time/1000,'%Y-%m-%d %h:%i:%s') ,bce.* from biz_cvent bce where bce.d ...
- 003-Java程序流程控制
3. Java程序流程控制(重点) 程序的三种控制结构 3.1 分支结构 if, switch 3.1.1 if if 分支 根据条件(真或假)来决定执行某段代码. if分支应用场景 if 第一种形式 ...
- C++ //案列-员工分组 ( 容器存放,查找,打印,统计,宏定义 ,随机)
//案列-员工分组//描述:公司招聘10个员工(ABCDEFGHIJ),10名指派员工进入公司,需要指派那个员工在那个部门工作//员工信息有:姓名 工资组成: 部门分为:策划 美术 研发//随机给10 ...
- redis迁移同步工具-redis-shake
官方文档: https://github.com/alibaba/RedisShake/wiki/快速开始:数据迁移 下载: https://github.com/alibaba/RedisShake ...
- Redis队列优先级的实现方案
场景 通常使用 list 来实现队列操作,所有的任务统一都是先进先出的原则,如果想优先处理某个任务就不太合适,这个时候就需要让队列有优先级的概念,实现方式有以下两种方式: 单一列表实现 队列正常的操作 ...