1. mysql -hlocalhost -uroot -p回车 进入mysql数据库
> -h表示服务器名,
>
> -u为数据库用户名,
>
> -p为密码
localhost表示本地,root是mysql默认用户名,如果设置了密码,可直接在-p后链接输入,如:-p123456,用户没有设置密码,显示Enter password时,直接回车即可
2. show databases; 返回可用数据库得一个列表
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| jpa |
| mvc |
| mysql |
| mytest |
| performance_schema |
| sys |
| test |
+--------------------+
3. use test; 选择数据库
mysql> use test;
Database changed
4. show tables; 返回当前选择的数据库内可用表的列表
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| demo |
+----------------+
5. show columns from 表名;
describe 表名;
要求给出一个表名,它对每个字段返回一行,行中包含字段名、数据类型、是否允许NULL、键信息、默认值以及其他信息(如字段auto_increment)
mysql> show columns from demo;
+--------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| name | char(10) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| gender | char(10) | YES | | NULL | |
+--------+----------+------+-----+---------+-------+
mysql> describe demo;
+--------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| name | char(10) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| gender | char(10) | YES | | NULL | |
+--------+----------+------+-----+---------+-------+
四、检索数据
1. select 列名 from 表名; 检索单个列
mysql> select name from demo;
+----------+
| name |
+----------+
| zhangsan |
| lisi |
| sjn |
| sjn |
+----------+
2. select 列名,列名,... from 表名; 检索多个列
mysql> select name,age,gender from demo;
+----------+------+--------+
| name | age | gender |
+----------+------+--------+
| zhangsan | 19 | male |
| lisi | 20 | female |
| sjn | 20 | male |
| sjn | 20 | male |
+----------+------+--------+
3. select * from 表名; 检索所有列
mysql> select * from demo;
+----------+------+--------+
| name | age | gender |
+----------+------+--------+
| zhangsan | 19 | male |
| lisi | 20 | female |
| sjn | 20 | male |
| sjn | 20 | male |
+----------+------+--------+
4. select distinct 列名 from 表名; 检索不同的行
mysql> select distinct name from demo;
+----------+
| name |
+----------+
| zhangsan |
| lisi |
| sjn |
+----------+
distinct关键字应用于所有列而不仅是前置它的列
5. select 列名 from 表名 limit 检索的行数; 限制结果
mysql> select name from demo limit 2;
+----------+
| name |
+----------+
| zhangsan |
| lisi |
+----------+
分析:limit 2指示MySQL返回不多于2行
mysql> select name from demo limit 2,2;
+------+
| name |
+------+
| sjn |
| sjn |
+------+
分析:limit 2,2指示MySQL返回从行2开始的2行。第一个数字为开始位置,第二个数为要检索的行数。
6. select 表名.列名 from 表名; 使用完全限定的表名
mysql> select demo.name from demo;
+----------+
| name |
+----------+
| zhangsan |
| lisi |
| sjn |
| sjn |
+----------+
五、排序检索数据
1. select 列名 from 表名 order by 列名; 排序数据
mysql> select name from demo order by name;
+----------+
| name |
+----------+
| lisi |
| sjn |
| sjn |
| zhangsan |
+----------+
分析:指示MySQL对name列以字母顺序排序数据
2. select 列名,列名,... from 表名 order by 列名,列名; 按多个列排序
mysql> select name,age from demo order by name,age;
+----------+------+
| name | age |
+----------+------+
| lisi | 20 |
| sjn | 20 |
| sjn | 20 |
| zhangsan | 19 |
+----------+------+
分析:仅在多个行具有相同的name时才对产品按age进行排序
3. select 列名,列名,... from 表名 order by 列名 DESC,列名; 指定排序方向
mysql> select name,age from demo order by age DESC,name;
+----------+------+
| name | age |
+----------+------+
| lisi | 20 |
| sjn | 20 |
| sjn | 20 |
| zhangsan | 19 |
+----------+------+
六、过滤数据
1. select 列名,列名,... from 表名 where 条件; 使用where语句
mysql> select * from demo where gender = 'female';
+------+------+--------+
| name | age | gender |
+------+------+--------+
| lisi | 20 | female |
+------+------+--------+
分析:在同时使用order by和where子句时,应该让order by位于where之后,否则将会产生错误
mysql> select * from demo where age <= 20;
+----------+------+--------+
| name | age | gender |
+----------+------+--------+
| zhangsan | 19 | male |
| lisi | 20 | female |
| sjn | 20 | male |
| sjn | 20 | male |
+----------+------+--------+
分析:筛选出年龄小于等于20的数据
mysql> select * from demo where gender = 'female';
+------+------+--------+
| name | age | gender |
+------+------+--------+
| lisi | 20 | female |
+------+------+--------+
分析:在同时使用order by和where子句时,应该让order by位于where之后,否则将会产生错误
mysql> select * from demo where age <= 20;
+----------+------+--------+
| name | age | gender |
+----------+------+--------+
| zhangsan | 19 | male |
| lisi | 20 | female |
| sjn | 20 | male |
| sjn | 20 | male |
+----------+------+--------+
分析:筛选出年龄小于等于20的数据
七、数据过滤
1. select 列名,列名,... from 表名 where 条件 and 条件; and操作符
mysql> select * from demo where name <> 'sjn' and age = 20;
+------+------+--------+
| name | age | gender |
+------+------+--------+
| lisi | 20 | female |
+------+------+--------+
分析:筛选出所有姓名不等于'sjn'并且年龄等于20的数据
2. select 列名,列名,... from 表名 where 条件 or 条件; or操作符
mysql> select * from demo where name <> 'sjn' or age != 20;
+----------+------+--------+
| name | age | gender |
+----------+------+--------+
| zhangsan | 19 | male |
| lisi | 20 | female |
+----------+------+--------+
分析:筛选出所有姓名不等于'sjn'或者年龄不等于20的数据
3. 计算次序
mysql> select prod_name,prod_price
-> from products
-> where vend_id = 1002 OR vend_id = 1003 and prod_price >= 10;
+----------------+------------+
| prod_name | prod_price |
+----------------+------------+
| Detonator | 13.00 |
| Bird seed | 10.00 |
| Fuses | 3.42 |
| Oil can | 8.99 |
| Safe | 50.00 |
| TNT (5 sticks) | 10.00 |
+----------------+------------+
分析:and在计算次序中优先级中更高,操作符被错误地组合了
mysql> select prod_name,prod_price
-> from products
-> where (vend_id = 1002 or vend_id = 1003) and prod_price >= 10;
+----------------+------------+
| prod_name | prod_price |
+----------------+------------+
| Detonator | 13.00 |
| Bird seed | 10.00 |
| Safe | 50.00 |
| TNT (5 sticks) | 10.00 |
+----------------+------------+
分析:此问题的解决方法是使用圆括号明确地分组相应的操作符
4. in操作符:in操作符用来指定条件范围,范围中的每个条件都可以进行匹配
mysql> select prod_name,prod_price
-> from products
-> where vend_id in (1002,1003)
-> order by prod_name;
+----------------+------------+
| prod_name | prod_price |
+----------------+------------+
| Bird seed | 10.00 |
| Carrots | 2.50 |
| Detonator | 13.00 |
| Fuses | 3.42 |
| Oil can | 8.99 |
| Safe | 50.00 |
| Sling | 4.49 |
| TNT (1 stick) | 2.50 |
| TNT (5 sticks) | 10.00 |
+----------------+------------+
分析:此select语句检索供应商1002和1003制造的所有产品
in操作符的优点:
1.在使用长的合法选项清单时,in操作符的语法更清楚且更直观
2.在使用in时,计算的次序更容易管理(因为使用的操作符更少)
3.in操作符一般比or操作符清单执行更快
4.in的最大优点是可以包含其他全select语句,使得能够更动态地建立where子句
5. not操作符:否定它之后跟的任何条件
mysql> select prod_name,prod_price
-> from products
-> where vend_id not in (1002,1003)
-> order by prod_name;
+--------------+------------+
| prod_name | prod_price |
+--------------+------------+
| .5 ton anvil | 5.99 |
| 1 ton anvil | 9.99 |
| 2 ton anvil | 14.99 |
| JetPack 1000 | 35.00 |
| JetPack 2000 | 55.00 |
+--------------+------------+
分析:匹配1002和1003之外供应商的vend_id
八、用通配符进行过滤
通配符:用来匹配值的一部分的特殊字符
1. like操作符:为在搜索子句中使用通配符,必须使用like操作符。like指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。
2. 百分号(%)通配符:%表示任何字符出现任意次数
mysql> select prod_id,prod_name
-> from products
-> where prod_name like 'jet%';
+---------+--------------+
| prod_id | prod_name |
+---------+--------------+
| JP1000 | JetPack 1000 |
| JP2000 | JetPack 2000 |
+---------+--------------+
分析:找出所有以词jet起头的产品
mysql> select prod_id,prod_name
-> from products
-> where prod_name like '%anvil%';
+---------+--------------+
| prod_id | prod_name |
+---------+--------------+
| ANV01 | .5 ton anvil |
| ANV02 | 1 ton anvil |
| ANV03 | 2 ton anvil |
+---------+--------------+
分析:通配符可在搜索模式中任意位置使用,并且可以使用多个通配符。'%anvil%'表示匹配任何位置包含文本anvil的值。
mysql> select prod_id,prod_name
-> from products
-> where prod_name like '%';
+---------+----------------+
| prod_id | prod_name |
+---------+----------------+
| ANV01 | .5 ton anvil |
| ANV02 | 1 ton anvil |
| ANV03 | 2 ton anvil |
| DTNTR | Detonator |
| FB | Bird seed |
| FC | Carrots |
| FU1 | Fuses |
| JP1000 | JetPack 1000 |
| JP2000 | JetPack 2000 |
| OL1 | Oil can |
| SAFE | Safe |
| SLING | Sling |
| TNT1 | TNT (1 stick) |
| TNT2 | TNT (5 sticks) |
+---------+----------------+
分析:除了一个或多个字符,%还能匹配0个字符
3. 下划线(_)通配符:_下划线的用途跟%一样,但下划线只匹配单个字符而不是多个字符
mysql> select prod_id,prod_name
-> from products
-> where prod_name like '_ ton anvil';
+---------+-------------+
| prod_id | prod_name |
+---------+-------------+
| ANV02 | 1 ton anvil |
| ANV03 | 2 ton anvil |
+---------+-------------+
分析:_总是匹配一个字符,不能多也不能少
4. 使用通配符的技巧
1.不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。
2.在确实需要使用通配符时,除非绝对有必要,否则不要把它们用在搜索模式的开始处,搜索起来是最慢的。
3.仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。
九、用正则表达式进行搜索
正则表达式:匹配文本,将一个模式(正则表达式)与一个文本串进行比较
1. 基本字符匹配
mysql> select prod_name
-> from products
-> where prod_name regexp '1000'
-> order by prod_name;
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
+--------------+
分析:regexp后面所跟的东西作为正则表达式(与文字正文1000匹配的一个正则表达式)处理。
mysql> select prod_name
-> from products
-> where prod_name regexp '.000'
-> order by prod_name;
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
分析:这里使用了正则表达式.000。.是正则表达式语言中一个特殊的字符。它表示匹配任意一个字符,因此,1000和2000都匹配且返回。
mysql> select prod_name
-> from products
-> where prod_name regexp binary 'JetPack .000';
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
匹配不区分大小写:MySQL中的正则表达式匹配不区分大小写。为区分大小写,可使用binary关键字,如where prod_name regexp binary 'JectPack .000'
2. 进行or匹配:为搜索两个串之一(或者为这个串,或者为另一个串),使用|
mysql> select prod_name
-> from products
-> where prod_name regexp '1000|2000'
-> order by prod_name;
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
分析:语句使用了正则表达式1000|2000.|为正则表达式的or操作符。它表示匹配其中之一,因此1000和2000都匹配并返回。
3. 匹配几个字符之一:匹配任何单一字符。但是,如果你只想匹配特定的字符,可通过指定一组用[和]括起来的字符来完成
mysql> select prod_name
-> from products
-> where prod_name regexp '[123] Ton'
-> order by prod_name;
+-------------+
| prod_name |
+-------------+
| 1 ton anvil |
| 2 ton anvil |
+-------------+
分析:这里使用了正则表达式[123] Ton。[123]定义一组字符,它的意思是匹配1或2或3,因此1 ton和2 ton都匹配且返回(没有3 ton)
[]是另一种形式的or语句。事实上,正则表达式[123]Ton为[1|2|3]Ton的缩写,也可以使用后者。
4. 匹配范围:集合可用来定义要匹配的一个或多个字符
[0-9]
范围不限于完整的集合,[1-3]和[6-9]也是合法的范围。此外,范围不一定只是数值的,[a-z]匹配任意字母字符。
mysql> select prod_name
-> from products
-> where prod_name regexp '[1-5] Ton'
-> order by prod_name;
+--------------+
| prod_name |
+--------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
+--------------+
分析:这里使用正则表达式[1-5] Ton。[1-5]定义了一个范围,这个表达式意思是匹配1到5,因此返回3个匹配行。由于5 ton匹配,所以返回.5 ton
5. 匹配特殊字符:为了匹配特殊字符,必须用\\为前导。\\-表示查找-,\\.表示查找.。
mysql> select vend_name
-> from vendors
-> where vend_name regexp '\\.'
-> order by vend_name;
+--------------+
| vend_name |
+--------------+
| Furball Inc. |
+--------------+
6. 匹配字符类:存在找出你自己经常使用的数字、所有字母字符或所有数字字母字符等的匹配。为更方便工作、可以使用预定义的字符集,称为字符类。
[:alnum:] 任意字母和数字
[:alpha:] 任意字符
[:blank:] 空格和制表
[:cntrl:] ASCII控制字符
[:digit:] 任意数字
[:graph:] 与[:print:]相同,但不包括空格
[:lower:] 任意小写字母
[:print:] 任意可打印字符
[:punct:] 既不在[:alnum:]又不在[:cntrl:]中的任意字符
[:space:] 包括空格在内的任意空白字符
[:upper:] 任意大写字母
[:xdigit:] 任意十六进制数字
7. 匹配多个实例
* 0个或多个匹配
+ 1个或多个匹配
? 0个或1个匹配
{n} 指定数组的匹配
{n,} 不少于指定数目的匹配
{n,m} 匹配数目的范围
mysql> select prod_name
-> from products
-> where prod_name regexp '\\([0-9] sticks?\\)'
-> order by prod_name;
+----------------+
| prod_name |
+----------------+
| TNT (1 stick) |
| TNT (5 sticks) |
+----------------+
分析:s后的?使s可选,因为?匹配它前面的任何字符的0次或1次出现
mysql> select prod_name
-> from products
-> where prod_name regexp '[[:digit:]]{4}'
-> order by prod_name;
+--------------+
| prod_name |
+--------------+
| JetPack 1000 |
| JetPack 2000 |
+--------------+
分析:[:digit:]匹配任意数字,因而它为数字的一个集合。{4}确切地要求它前面的字符(任意数字)出现4次,所以[[:digit:]]{4}匹配连在一起的任意4位数字。
8. 定位符:为了匹配特定位置的文本,需要使用下面列出的定位符
^ 文本的开始
$ 文本的结束
[[:<:]] 词的开始
[[:>:]] 词的结尾
mysql> select prod_name
-> from products
-> where prod_name regexp '^[0-9\\.]'
-> order by prod_name;
+--------------+
| prod_name |
+--------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
+--------------+
分析:^匹配串的开始。因此,^[0-9\\.]只在.或任意数字为串中第一个字符时才匹配它们。
十、创建计算字段
1. 拼接(concatenate)将值联结到一起构成单个值
mysql> select concat(vend_name,'(',vend_country,')')
-> from vendors
-> order by vend_name;
+----------------------------------------+
| concat(vend_name,'(',vend_country,')') |
+----------------------------------------+
| ACME(USA) |
| Anvils R Us(USA) |
| Furball Inc.(USA) |
| Jet Set(England) |
| Jouets Et Ours(France) |
| LT Supplies(USA) |
+----------------------------------------+
分析:concat()拼接串,即把多个串连接起来形成一个较长的串
mysql> select concat(RTrim(vend_name),'(',RTrim(vend_country),')')
-> from vendors
-> order by vend_name;
+------------------------------------------------------+
| concat(RTrim(vend_name),'(',RTrim(vend_country),')') |
+------------------------------------------------------+
| ACME(USA) |
| Anvils R Us(USA) |
| Furball Inc.(USA) |
| Jet Set(England) |
| Jouets Et Ours(France) |
| LT Supplies(USA) |
+------------------------------------------------------+
分析:RTrim()函数去掉值右边得所有空格。
2. 使用别名
mysql> select concat(RTrim(vend_name),'(',RTrim(vend_country),')') as vend_title
-> from vendors
-> order by vend_name;
+------------------------+
| vend_title |
+------------------------+
| ACME(USA) |
| Anvils R Us(USA) |
| Furball Inc.(USA) |
| Jet Set(England) |
| Jouets Et Ours(France) |
| LT Supplies(USA) |
+------------------------+
分析:as vend_title指示SQL创建一个包含指定计算的名为vend_title的计算字段
3. 执行算术计算
mysql> select prod_id,quantity,item_price,quantity*item_price as expanded_price
-> from orderitems
-> where order_num = 20005;
+---------+----------+------------+----------------+
| prod_id | quantity | item_price | expanded_price |
+---------+----------+------------+----------------+
| ANV01 | 10 | 5.99 | 59.90 |
| ANV02 | 3 | 9.99 | 29.97 |
| TNT2 | 5 | 10.00 | 50.00 |
| FB | 1 | 10.00 | 10.00 |
+---------+----------+------------+----------------+
分析:输出中现实的expand_price列为一个计算字段,此计算为quantity*item_price
十一、使用数据处理函数
1. 文本处理函数
常用的文本处理函数:
Left() 返回串左边的字符
Length() 返回串的长度
Locate() 找出串的一个子串
Lower() 将串转换成小写
LTrim() 去掉串左边的空格
Rigtht() 返回串右边的字符
RTrim() 去掉串左边的空格
Soundex() 返回串的SOUNDEX值
SubString() 返回字串的字符
Upper() 将串转换为大写
mysql> select vend_name,Upper(vend_name) as vend_name_upcase
-> from vendors
-> order by vend_name;
+----------------+------------------+
| vend_name | vend_name_upcase |
+----------------+------------------+
| ACME | ACME |
| Anvils R Us | ANVILS R US |
| Furball Inc. | FURBALL INC. |
| Jet Set | JET SET |
| Jouets Et Ours | JOUETS ET OURS |
| LT Supplies | LT SUPPLIES |
+----------------+------------------+
分析:Upper()将文本转换为大写
2. 日期和时间处理函数
常用日期和时间处理函数:
AddDate() 增加一个日期(天、周等)
AddTime() 增加一个时间(时、分等)
CurDate() 返回当前日期
CurTime() 返回当前时间
Date() 返回日期时间的日期部分
DateDiff() 计算两个日期之差
Date_Add() 高度灵活的日期运算函数
Date_Format() 返回一个格式化的时间或时间串
Day() 返回一个日期的天数部分
DayOfWeek() 对于一个日期,返回对应的星期几
Hour() 返回一个时间的小时部分
Minute() 返回一个时间的分钟部分
Month() 返回一个日期的月份部分
Now() 返回当前日期和时间
Second() 返回一个时间的秒部分
Time() 返回一个日期时间的时间部分
Year() 返回一个日期的年份部分
mysql> select cust_id,order_num
-> from orders
-> where Date(order_date) = '2005-09-01';
+---------+-----------+
| cust_id | order_num |
+---------+-----------+
| 10001 | 20005 |
+---------+-----------+
分析:Date(order_date)指示MySQL仅提取列的日期部分
mysql> select cust_id,order_num
-> from orders
-> where date(order_date) between '2005-09-01' and '2005-09-30';
+---------+-----------+
| cust_id | order_num |
+---------+-----------+
| 10001 | 20005 |
| 10003 | 20006 |
| 10004 | 20007 |
+---------+-----------+
分析:检索出2005年9月下的所有订单
mysql> select cust_id,order_num
-> from orders
-> where year(order_date) = 2005 and month(order_date) = 9;
+---------+-----------+
| cust_id | order_num |
+---------+-----------+
| 10001 | 20005 |
| 10003 | 20006 |
| 10004 | 20007 |
+---------+-----------+
分析:检索出2005年9月下的所有订单
3. 数值处理函数
常用数值处理函数:
Abs() 返回一个数的绝对值
Cos() 返回一个角度的余弦
Exp() 返回一个数的指数值
Mod() 返回除操作的余数
Pi() 返回圆周率
Rand() 返回一个随机数
Sin() 返回一个角度的正弦
Sqrt() 返回一个角度的平方根
Tan() 返回一个角度的正切
十二、汇总数据
1. 聚集函数:运行在行组上,计算和返回单个值的函数
AVG() 返回某列的平均值
COUNT() 返回某列的行数
MAX() 返回某列的最大值
MIN() 返回某列的最小值
SUM() 返回某列值之和
2. AVG函数:通过对表中行数计数并计算特定列值之和,求得该列的平均值
mysql> select avg(prod_price) as avg_price
-> from products;
+-----------+
| avg_price |
+-----------+
| 16.133571 |
+-----------+
NULL值;AVG()函数忽略列值为NULL的行
3. COUNT()函数:进行计数
COUNT()函数有两种使用方式:
1.使用COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值
2.使用COUNT(column)对特定列中具有值的行进行计数,忽略NULL值
mysql> select count(cust_email) as num_cust
-> from customers;
+----------+
| num_cust |
+----------+
| 3 |
+----------+
分析:只对具有电子邮件地址的客户计数
4. MIN()函数:返回指定列的最小值
mysql> select count(prod_price) as min_price
-> from products;
+-----------+
| min_price |
+-----------+
| 14 |
+-----------+
分析;返回products表中最便宜物品的价格
5. SUM()函数:返回指定列值的和(总计)
mysql> select sum(quantity) as items_ordered
-> from orderitems
-> where order_num = 20005;
+---------------+
| items_ordered |
+---------------+
| 19 |
+---------------+
分析:返回订单中所有物品数量之和,where语句保证只统计某个物品订单中的物品
6. 组合聚集函数
mysql> select count(*) as num_items,
-> min(prod_price) as price_min,
-> max(prod_price) as price_max,
-> avg(prod_price) as price_avg
-> from products;
+-----------+-----------+-----------+-----------+
| num_items | price_min | price_max | price_avg |
+-----------+-----------+-----------+-----------+
| 14 | 2.50 | 55.00 | 16.133571 |
+-----------+-----------+-----------+-----------+
分析:这里用单条select语句执行了4个聚集计算,返回4个值(products表中物品的数目,产品价格的最低,最高以及平均值)
十三、分组数据
1. 创建分组:分组是在select语句的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 |
+---------+-----------+
分析:vend_id包含产品供应商的ID,num_prods为计算字段(count(*)函数建立)。group by子句指示MySQL按vend_id排序并分组数据。
在具体使用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子句之前。
2. 过滤分组:where过滤指定的是行而不是分组,为此提供了另外的子句,就是having子句
mysql> select cust_id,count(*) as orders
-> from orders
-> group by cust_id
-> having count(*) >= 2;
+---------+--------+
| cust_id | orders |
+---------+--------+
| 10001 | 2 |
+---------+--------+
分析:这条select语句的前3行类似于上面的语句。最后一行增加了having子句,它过滤count(*) > 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个(含)以上,价格为10(含)以上的产品的供应商
3. 分组和排序
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 |
+-----------+------------+
分析:group by子句用来按订单号(order_num列)分组数据,以便sum(*)函数能够返回总计订单价格。
having子句过滤数据,使得只返回总计订单大于等于50的订单。最后用order by子句排序输出。
4. select子句顺序
select子句及其顺序:
子句 说明 是否必须使用
select 要返回的列或表达式 是
from 从中检索数据的表 仅在从表选择数据时使用
where 行级过滤 否
group by 分组说明 仅在按组计算聚集时使用
having 组级过滤 否
order by 输出顺序排序 否
limit 要检索的行数 否