朝花夕拾 Mysql笔记2
欢迎扫码关注微信公众号"野心与家"回复"12.11MySQL2"获取源文件
4.1 简单查询
>4.1.1 select 语句
语法 //顺序不能颠倒
mysql> > select [distinct] * |字段名1,字段名2,字段名3,...
> from 表名
> [where 条件表达式1]
> [group by 字段名 [having条件表达式2]]
> [order by 字段名 [asc|desc]]
> [limit [offset] 记录数]
>4.1.2 查询所有字段
> 1.在select语句中指定所有字段
语法:select 字段名1,字段名2,...from 表名
> 2.在select语句中使用星号(*)通配符代替所有字段
select * from 表名
>4.1.3 查询指定字段
语法: select 字段名1,字段名2,...from 表名;
4.2 按条件查询
>4.2.1带关系运算符查询
where 子句中指定查询条件对数据进行过滤
语法:select 字段名1,字段名2,... from 表名 where 条件表达式
>4.2.2 带in关键字的查询
in关键字用于判断某个字段的值是否在指定集合中
语法:select * |字段名1,字段名2,... from 表名 where 字段名[not] in (元素1,元素2)
"元素1,元素2"表示集合中的元素,即指定的条件范围
not 为可选参数,使用not表示查询不在in关键字指定集合范围的记录
例如:查询student表中ID值为1,2,3的记录
mysql> select id,grade,name,grade from student where id in(1,2,3);
>4.2.3带between and 关键字查询
between and 用于判断某个字符的值是否在指定的范围之内,如果字段的值在指定的范围内,则满足条件
select * |{字段名1,字段名2,...} from 表名 where 字段名 [not] between 值1 and 值2
例如: 查询student表中id值在2~5之间的学生姓名
mysql> select id,name from student where id between 2 and 5;
>4.2.4 空值查询
在数据表中,某些列的值可能为空值(null),空值不同于0,也不同于空字符串
在mysql中,使用is null关键字来判断是否为空值
语法:select * |字符段1,字符段2,... from 表名 where 字段名 is [not] null;
例如:查询Student表中gender为空值的记录
mysql> select id,name,grade,gender from student where gender is null;
>4.2.5 带distinct关键词的查询
很多表中某些字段的数据存在重复的值,使用distinct过滤重复记录的字段
例如:在student表中查询gender(性别)字段的值,查询记录不能重复;
mysql> select distinct gender from student;
distinct关键字作用于多个字段,如果字段名1字段名2里的值都相同才被认为是重复记录
语法:select distinct 字段名1,字段名2,...from 表名;
>4.2.6 带like关键字的查询
使用关系运算符"="可以判断两个字符串是否相等,但有些需要是对字符串进行模糊查询
select * | {字符段1,字符段2,...}
from 表名
where 字段名 [not] like '匹配字符串';
1. 百分号(%) 通配符
作用 : 匹配任意长度的字符串 ,包括空字符串
例1: 查询student表中name字段值以字符"s"开头的学生 id
mysql> select id, name from student where name like "s%" ;
例2:查询student表中name字段值以字符"w"开头,以字符"g"结束的学生 id
mysql> select id, name from student where name like "w%g" ;
例3:查询student表中name字段值包括字符"y"的学生 id;
mysql> select id, name from student where name like "%y%" ;
2. 下划线(_) 通配符
作用 : 下划线通配符只能匹配单个字符,如果需要匹配多个则需要使用多个下划线
例1: 查询student表中name字段值以字符串"wu"开始, 以字符串"ong"结尾,并且两个字符串之间只有一个字符的记录
mysql> select * from student where name like "wu_ong";
例2: 查询student表中name字符值包括7个字符, 并且以字符串"ing"结尾的记录
mysql> select * from student where name like "_______ing";
3.使用百分号和下划线通配符进行查询操作
作用 : 通过右斜线( " \ " )对百分号和下划线进行转义
例如 : "%"匹配百分号字符值 , " \ _ "匹配下划线字符值
例如: 查询student表中name字段值包括"%"的记录;
mysql> insert into student (name,grade,gender)
-> values ('sun%er',95,'男');
mysql> select * from student where name like "%\%%";
>4.2.7 带and关键字的多条件查询
and关键字连接两个或以上查询条件
例如:select * from 表名 where 条件表达式1 and 条件表达式2 [...and 条件表达式n]
查询student表中id字段值在1.2.3.4之中,name字符值以字符串'ng'结尾,并且grade字段值小于80的记录
mysql> select id,name,grader,gender
-> from student
-> where id in(1,2,3,4) and name like '%ng' and grade <80;
>4.2.8 带or关键字的多条件查询
or关键字满足一个,可以连接两个或多个查询条件
例如:查询student表中满足条件name字段值以字符'h'结束,或者gender字符值为'女',或者grade字段值为100的记录
mysql> select id,name,grade,gender
-> from student
-> where name like '%h' or gender='女' or grade=100;
注意:or和and可以一起使用, and优先级高于or
例如:查询student表中student字符值为'女'或者gender字符值为'男',并且gender字段值为100的学生姓名
mysql> select name,grade,gender
-> from student
-> where gender='女' or gender ='男' and grade=100;
4.3 高级查询
>4.3.1 聚合函数
>1.count()函数
COUNT()函数用来统计记录的条数,其语法格式如下所示:
SELECT COUNT(*) FROM 表名;
例如: 查询student表中一共有多少条记录
mysql> select count(*) from student;
>2.sum()函数
SUM()是求和函数,用于求出表中某个字段所有值的总和,其语法格式如下:
SELECT SUM(字段名) FROM 表名
例如:求出student表中grade字段的总和
mysql> select sum(grade) from student7
>3.avg()函数
AVG()函数用于求出某个字段所有值的平均值其语法格式如下所示:
SELECT AVG(字段名) FROM student;
例如:求出student表中grade字段的平均值
>select avg(grade) from student
>4.max()函数
MAX()函数是求最大值的函数,用于求出某个字段的最大值,其语法格式如下所示:
SELECT MAX(grade) FROM student;
例如:求出student表中grade字段的最大值
>select max(grade) from student
>5.min()函数
MIN()函数是求最小值的函数,用于求出某个字段的最小值,其语法格式如下所示:
SELECT MIN(grade) FROM student;
例如:求出student表中grade字段的最小值
>select min(grade) from student
>4.3.2 对查询结果排序
从表中查询出来的数据可能是无序的,或者排列顺序不是用户期望的,为了使查询结果满足用户的要求,可以使用order by
对查询结果进行排序,语法格式如下:
使用 ORDER BY对查询结果进行排序其语法格式如下所示:
SELECT字段名1, 字段名2, FROM 表名
ORDER BY字段名1 [ASC|DESC],字段名2 [ASC|DESC] /*asc:升序,从小到大,desc:倒叙,从大到小*/
例2:查询student表中的所有记录,按照gender字段的升序和grade字段的降序进行排序:
mysql> select * from student
-> order by gender asc, grade desc;
==注意:==在按照指定字段进行升序排列时,如果某条记录的字段值为NULL,则这条记录会在第一条显示,这是因为NULL值可以被认为是最小值
> 4.3.3 分组查询
>1.单独使用group by 分组
单独使用group by 关键词,查询的是每个分组的一条记录
例如:查询student表中的记录,按照gender字段值进行分组
select * from student group by gender;
查询结果是按照gender字段中的不同值进行分类的,查询结果只显示每个分组
>2.group by和聚合函数一起使用
gruop by 和聚合函数一起使用可以统计出某个或者某些字段在一个分组中的最大值,最小值,平均值等
例如:将student表中gender字段值进行分组查询,计算出每个分组中各有多少名学生
select count(*),gender from student group by gender;
例如:将student表中gender字段值进行分组查询,计算出每个分组的总成绩,平均成绩,最高分,最低分
select sum(grade),avg(grade),max(grade),min(grade),genter from student3 group by genter;
>3. group by 和 having关键词一起使用
having关键字和 where关键字的作用相同,都设置条件表达式对查询结果进行过滤,两者区别在于,
having关键字后可以跟聚合函数,而where 关键字不能
例如:将student表中按照gender字段进行分组查询,查找grade字段值之和小于300的分组
select student sum(grade),gender from student group by gender having sum(grade)<300
>4.3.4 使用limit限制查询结果的数量
查询数据时,可能会返回很多条记录,而用户需要的记录可能只是其中的一条或者几条,比如实现分页功能,每页显示10行信息,每次查询都需要查出10条记录
格式:select 字段名1,字段名2,...
from 表名
limit [offset,] 记录数 //limit后可以跟两个参数,第一个参数offset表示偏移量,如果为0则从查询结果的第一条开始记录,偏移量为1则从查询结果中的第二条记录开始,以此类推;offset为可选值,如果不指定其默认值为0.第二个参数"记录数"表示返回查询记录的条数;
例(1):查询Student表中的前四条记录
select * from student limit 4; //没有指定返回记录的偏移量,只指定了查询记录的条数4,因此返回结果从第一条开始,一共返回4条记录;
例(2):查询student表中grade字段值从第五位到第八位的学生(从高到低)
select * from student group desc limit 4,4
limit后面第一个参数表示偏移量位4,即从第五条开始查询,第二个参数表示一共返回4条记录,即从第五位到第8为学生
>4.3.5 函数(列表)
函数名称 | 作用 |
---|---|
ABS(x) | 返回x的绝对值 |
SQRT(x) | 返回x的非负2次方根 |
MOD(xy) | 返回x被y除后的余数 |
CEILING(x) | 返回x的绝对值 |
FLOOR(z) | 返回x的绝对值 |
ROUND(x,y) | 返回x的绝对值 |
TRUNCATE(x) | 返回x的绝对值 |
SIGN(x)2 | 返回x的绝对值 |
4.4 为表和字段取别名
> 4.4.1 为表取别名
在查询操作时,如果表名很长使用起来就不太方便,这时可以为表取一个别名,用这个别名来代替表的名称;
语法: select * from 表名 [as] 别名; as关键字用于指定表名的别名,它可以省略不写;
例如: 为student表起一个别名 s,并查询student表中gender字段值为'女'的记录
select * from student as s where s.gender='女';
student as s表示student表的别名为s
s.gender 表示student表中的gender字段;
> 4.4.2 为字段取别名
为了让显示查询结果更加直观,可以为字段取一个别名
select 字段名 [as] 别名 [,字段名 [as] 别名,...] from 表名;
例如:查询student表中的所有记录的name和grade字段值,并为这两个字段名起别名stu_name和stu_genter;
select * from name as stu_name, grader as stu_genter from student;
5.1 外键
> 5.1.1 什么是外键
外键是指引用另一个表中的一列或多列,==被引用的列应该具有主键约束或唯一性约束.==外键用来建立和加强两个表数据之间的连接
引入外键后,外键列只能插入参照列存在的值,参照列被参照的值不能被删除,这就确保了数据的参照完整性
创建两个表,一个班级表(grade),一个学生表(student)
create table grade(
id int(4) not null primary key,
name varchar(36)
);
create table student(
sid int(4) not null primary key,
sname varchar(36),
gid int(4) not null
);
学生表(student)中的gid 是学生所在的班级id,是引入了班级表(grade) 中的主键id,那么gid就可以作为表student的主键…被引用的表,即表grade是主表;引用外键的表,即表student是从表,两个表是主从关系.
表student用gid可以连接表grade中的信息
>5.1.2 为表中添加外键约束
语法: alter table 表名 add constraint FK_ID foreign key(外键字段名) references 主表表名(主键字段名);
语句: alter table student add constraint FK_ID foreign key(gid) references grade(id);
>5.1.3 删除外键约束
在实际开发中,根据业务逻辑的需求,需要解除两个表的关联关系时, 就需要删除外键约束
语法: alter table 表名 drop foreign key 外键名;
接下来,将表中student表的外键约束删除
alter table student drop foreign key FK_ID;
5.2 操作关联表
>5.2.1 关联关系
1.多对一 (外键定义在多端)
一个部门可以有多个员工,而一个员工不能属于多个部门。
在多对一的表关系中,应该将外键建在多的一方
2.多对多 (需定义中间表)
一个老师可以教多个学生,同时一个学生可以上多个老师的课程。
为了实现数据表多对多的关系,需要定义一张第三方中间表,该表保存两个关系表的外键。
3.一对一 (从表依赖主表)
一对一的对应关系中,需要分清主从关系,通常在从表中建立外键
>5.2.2 添加数据
在开发中,最常见的关联关系就是多对一关系
为表student和表grade中添加外键约束来建立两个表的关联关系
alter table student add constraint FK_ID foreign key(gid) references grade (id);
>5.2.3 删除数据
由于grade表与student表之间具有关联关系 , 参照列被参照的值不能被删除的,再删除软件二班时需要删除软件二班的所有学生
delete from student where sname='王红';
delete from student where sname='李强';
delete * from grade where id=2;
5.3 连接查询
> 5.3.1交叉连接
交叉连接返回的结果是被连接的两个表中所有数据行的笛卡尔积即行数的乘积
例如:department表中有4个部门,employee表中有4个员工,那么交叉连接的结果就有4X4=16条数据
语法: select *from 表1,表2;
或select * from 表1 cross join 表2;
> 5.3.2 内连接
内连接(INNER JOIN)又称简单连接或自然连接,内连接使用比较运算符对两个表中的数据进行比较,列出与连接条件匹配的数据行,组合成新的记录
简单连接或自然连接,返回的结果是两个表中一一对应的数据,只有满足条件的数据才显示
语法:select 查询字段 from 表1[inner] join 表2 on 表1.关系字段= 表2.关系字段
例如: 在department表和employee表之间使用内连接查询;
select employee.name,department.dname from department inner join employee on department.did=employee.did; //只有department.did和employee.did相等的才输出
使用where条件语句来实现同样的功能;
例如:在department表和employee表之间使用where:
select employee.name, department.dname from department,employee where department,did=employee.did;
注意:where子句的查询结果与使用inner join的查询结果是一致的,虽然结果相同,但inner join 是内连接语句,where是条件判断语句,在where语句后可以添加其他条件,而inner join语句不可以;
如果在一个连接查询中,涉及的两个表是同一个表,这种查询称为自连接查询,指的是相互连接的表在物理上为同一个表,但逻辑上分为两个表
查询部门为2的员工的姓名和年龄;
select department.did,employee.name,employee.age from department join employee on department.did=employee.did where department.did=2;
或
select department.did,employee.name,employee.age from department,employee where department.did=employee.did and department.did=2;
查询姓名为王红所在的部门编号和部门名称
select employee.name,department.did,department.dname from department,employee where department.did=employee.did and employee.name='王红';
自连接:
例如:在department表和employee表之间使用自连接查询王红所在的部门有哪些员工;
select p1.* from employee p1 inner join employee p2 on p1.did=p2.did where p2.name='王红'; /*p1 p2为别名*/
或select p1.* from employee p1,employee p2 where p1.did=p2.did and p2.name='王红';/*where方法*/
> 5.3.3 外连接
外连接分为左连接和有连接
左连接的结果包括LEFT JOIN子句中指定的左表的所有记录,和所有满足连接条件的记录。如果左表的某条记录在右表中不存在,则在右表中显示为空 ;
右连接与左连接正好相反,返回右表中所有指定的记录和所有满足连接条件的记录。如果右表的某条记录在左表中没有匹配,则左表将返回空值 ;
做外链接:左表中的所有记录以及内连接的记录(放在前面的是左表)
右外连接:右表中的所有记录以及内连接的记录
语法: SELECT 所查字段 FROM 表1 LEFT|RIGHT [OUTER] JOIN 表2
ON 表1.关系字段 = 表2.关系字段 WHERE 条件
select * from 表1,表2 where表1.关系字段=表2.关系字段 and 其他条件
>全外连接查询
在外连接的基础上,增加左边表有,右边表没有的记录,以及右边表有左边表没有的记录
语法: select * from 表1 full jion 表二 on 表一.关系字段=表二.关系字段;
select * from dep full jion emp on dep.did=em.did;
>5.3.4 复合条件查询
5.4 子查询
>5.4.1 带IN关键字的子查询
使用in关键字进行子查询时,内层查询语句仅返回一个数列值,这个数列值中的值将供外层查询语句进行比较操作
例如:查询存在年龄为20岁的员工的部门
select * from department where did in(select did from employee where age=20);
或 //子查询方法
select department.did,department.dname from department join employee on department.did=employee.did where employee.age=20; //内连接方法
或
select department.did,department.dname from department,employee where department.did=employee.did and employee.age=20; //where方法
>5.4.2 带exists关键字的子查询
exists关键字后面的参数可以是任意一个子查询,这个子查询的作用相当于测试,他不产生任何数据,只返回true或false,当返回值为true时,外层查询才会执行
例如:查询employee表中是否存在年龄大于21岁的员工,如果存在,则查询department表中的所有记录
select * from department where exists(select did from employee where age>21);
> 5.4.3 带any关键字的子查询
any关键字表示满足其中任意一个条件,它允许创建一个表达式对子查询的返回值列表进行比较
例如:
select * from department where did>any(select did from employee);//列出只要大于employee.did任意一个数
>5.4.4 带all关键字的子查询
例如:
select * from department where did>all(select did from employee);/列出大于employee.did所有的数
>5.4.5 带比较运算符的子查询
比较运算符 > , < , = , >= , <= , ! =
例如:使用比较运算符的子查询,查询赵四是哪个部门的员工
select * from department where did=(select did from employee where name ="赵四");
6.1 事务管理
> 6.1.1 事务的概念
所谓的事务就是针对数据库的一组操作,它可以由一条或多条SQL语句组成,同一个事务的操作具备同步的特点,即事务中的语句要么都执行,要么都不执行
开启事务的语法: start transaction
上述语句用于开启事务,事务开启之后就可以执行SQL语句,SQL语句执行成功后,需使用相对应语句提交事务,语法如下:
提交事务的语法: commit
在操作一个事务时,如果发现当前事务中的操作是不合理的,此时只要还没有提交事务,就可以通过回滚来取消当前事务
事务回滚语句: rollback