一、SQL查询
SQL查询的执行顺序,先对表中现有的字段进行筛选(1、where),再进行聚合分组(2、group),然后根据查询条件进行查找(3、select),紧接着对筛选的结果在再筛选(4、having),接下来根据条件进行排序(5、order),最后对记录的显示进行限制(6、limit)。
3、select ...聚合函数 from 表名
1、where ...
2、group by ...
4、having ...
5、order by ...
6、limit ...;
1、order by
给查询的结果进行排序
语法:order by 字段名 排序方式
排序方式
a、升序 :ASC(默认)
b、降序 :DESC
1、将蜀国的英雄按照攻击值从高到低排序
select * from sanguo
where country='蜀国'
order by gongji DESC;
2、将魏蜀两国的男英雄中名字为三个字符的英雄按防御值升序排列
select * from sanguo
where country in('蜀国','魏国') and sex='男' and name like '___'
order by fangyu ASC;
2、limit(永远放在SQL语句的最后)
限制显示查询记录的个数
a、用法
1)limit n -->显示n条记录
2)limit m,n
m :表示从 m+1 条记录开始显示
n :表示显示 n 条
limit 2,4 :显示第3、4、5、6四条记录
limit 0,2 :显示第1、2两条记录
b、示例1、在蜀国英雄中查找攻击值前三名且名字不为NULL的英雄姓名、攻击值和国家
select name,gongji,country from sanguo
where country='蜀国' and name is not NULL
order by gongji DESC
limit 3;
2、在蜀国英雄中,查找防御值倒数第2名至倒数第4名的英雄信息
select * from sanguo
where country='蜀国' order by fangyu limit 1,3;
c、分页查询
每页显示5(n)条记录,显示第4(m)页
第1页:limit 0,5 ## 1 2 3 4 5
第2页:limit 5,5 ## 6 7 8 9 10 ## (2-1)*5
第3页:limit 10,5 ## 11 12 13 14 15 ##(3-1)*5
第4页:limit 15,5 ## 16 17 18 19 20 ##(4-1)*5
分页公式:limit (m-1)*n,n m:第几页 n:每页显示记录条数
3、聚合函数
avg(字段名) : 平均值
max(字段名) : 最大值
min(字段名) : 最小值
sum(字段名) : 求和
count(字段名) : 统计该字段记录的个数
1、攻击力最强值
select max(gongji) as best from sanguo;
2、统计一下表中id、name字段分别有多少条记录
select count(id),count(name) from sanguo;
## 空值NULL不会被统计
select count(*) from sanguo;
3、统计蜀国英雄中攻击值大于200的英雄的数量
select count(*) from sanguo where country='蜀国' and gongji > 200;
4、group by(先分组-再聚合-去重)
给查询的结果进行分组
a、示例
计算所有国家的平均攻击力,显示国家名和平均攻击力
select country,avg(gongji) from sanguo group by country;
先分组 - 再聚合 - 去重
蜀国
蜀国 400 蜀国
蜀国
魏国 300 魏国
魏国
吴国 200 吴国
查找所有国家中,英雄数量最多的前2名,显示国家名称和英雄数量
select country,count(*) as number from sanguo
group by country
order by number DESC limit 2;
b、注意
1)group by之后的字段名必须要为select之后的字段名
2)如果select后的字段名和group by之后的字段不一致,则必须对该字段进行聚合处理(聚合函数)
5、having
对查询结果进一步筛选找出平均攻击力大于105的国家的前2名,显示国家名称和平均攻击力
select country,avg(gongji) from sanguo
group by country
having avg(gongji)>105
order by avg(gongji) DESC limit 2;
注意
1)having语句通常与group by语句联合使用,用来过滤由group by语句返回的记录集
2)having语句的存在弥补了where条件子句不能与聚合函数联合使用的不足,where操作的是表中实际存在的字段,having操作的是聚合函数生成的显示列
6、distinct
不显示字段的重复值
1、sanguo表中有哪些国家
select distinct country from sanguo;
2、计算魏国一共有多少个英雄
select count(distinct name) from sanguo
where country='魏国';
注意
1)distinct处理的是distinct和from之间的所有字段,所有字段的值必须完全相同才可以去重
2)distinct不能对任何字段做聚合处理
7、查询表记录时的数学运算
a、运算符
+ - * / %
b、示例查询时显示所有英雄的攻击力 * 10
select name,gongji*10,country from sanguo;
二、约束
1、作用 为了保证数据的完整性、一致性、有效性,可以限制无效的数据插入到数据表中
2、约束分类
a、默认约束(default) 在插入记录时,如果不给该字段赋值,则使用默认值
格式:字段名 数据类型 default 默认值,
create table tt(sex enum('男','女','保密') default '保密');
desc tt ;
b、非空约束 不允许该字段的值有空值NULL记录
格式:字段名 数据类型 not null,
create table xx(id int not null,name varchar(20) not null);
desc xx;
三、嵌套查询(子查询)
把内层的查询结果作为外层的查询条件
格式:select ... from 表名 where 字段名 运算符(select ....);
1、把攻击值小于 平均攻击值 的名字和攻击值显示出来(分两步)
select name,gongji from MOSHOU.sanguo
where gongji < (select avg(gongji) from MOSHOU.sanguo);
2、找出每个国家攻击力最高的英雄名字和攻击值
select name,gongji from sanguo
where (country,gongji) in (select country,max(gongji) from sanguo group by country);
四、附录1:数据库数据创建
为了方便,建立直接复制、黏贴以下代码,快速创建数据库和表。create database MOSHOU;
use MOSHOU;
create table hero(
id int,
name char(15),
sex enum('男','女'),
country char(10)
)default charset=utf8;
insert into hero values
(1,'曹操','男','魏国'),
(2,'小乔','女','吴国'),
(3,'诸葛亮','男','蜀国'),
(4,'貂蝉','女','东汉'),
(5,'赵子龙','男','蜀国'),
(6,'魏延','男','蜀国');
use MOSHOU;
create table sanguo(
id int,
name char(20),
gongji int,
fangyu tinyint unsigned,
sex enum('男','女'),
country varchar(20)
)default charset=utf8;
insert into sanguo values
(1,'诸葛亮',120,20,'男','蜀国'),
(2,'司马懿',119,25,'男','魏国'),
(3,'关6羽',188,60,'男','蜀国'),
(4,'赵云666',200,66,'男','魏国'),
(5,'8孙权',110,20,'男','吴国'),
(6,'貂蝉',666,10,'女','魏国'),
(7,null,1000,99,'男','蜀国'),
(8,'',1005,88,'女','蜀国');
五、附录2