MySQL 增改删查、多表查询


 

mysql关键字不区分大小写
 

数据库、数据表常用操作

show databases;  --查看所有的数据库
use db_student;  --操作某个数据库之前要先用use指定要使用数据库

show tables;  #查看当前数据库中的表

 

记录的增改删查

select id,username,tel from tb_user;
select * from tb_user;


insert into tb_user (username,tel) values ('chy','188xxxxx'; 

insert into tb_user (username,tel) values ('chy1,'188xxxx'),('chy2','187xxxxx');  --同时插入多条记录,()之间逗号隔开

insert into tb_user values ('chy','188xxxxx');  --插入所有字段时可不指定字段名


update tb_user set username='chy',age=20 where id=1
update tb_user set age=age+2 where id=1;  --在原值的基础上修改


delete from tb_user where id=1

字符串、日期时间类型的值要引起来,mysql不分区单双引

 

where子句

where id=1

where id<>1  --  <>是关系数据库通用的不等号
where id!=1  --mysql也可以用!=

--  >   >=   <   <=


where id between 1 and 10  -- [1,10],闭区间

where id in(1,3,9)  -- id=1或id=3或id=9


where id < all(1,3,9)  -- id要小于集合中的任何一个元素
where id < all(select id from tb_user where age<20)  -- 一般和子查询搭配使用

where id <any(1,3,9)  #id小于集合中的任意一个元素即可,id可以是[1,8]。一般和子查询搭配使用


where score>60 and score<90
where score<60 or score>90
where dep not in ("cs","math")  -- not表示非,常和其它关键字搭配使用


where score is null 
where score is not null  -- 不能直接not null


-- 模糊匹配
where name like '张%'  --以张开头
where name like '%伟'  --以伟结尾
where name like '%国%' --含有国

%  -- 一个或多个字符
_  -- 任意一个字符

[abcd]  -- abcd中的任意一个字符,[]只代表一个字符,eg. '张[杰伟]' 匹配张杰、张伟
[!abcd]  -- 只要不是abcd中的任意一个字符就行,eg. '张[!杰伟]'  只要不是张杰、张伟就ok
[^abcd]  -- !也可以写成^

 

查询常用

select distinct username from tb_user;  -- distinct 去重,如果结果集中有完全相同的记录,只保留一条

select price*number from tb_order_item where id=1;  -- 数值型可以进行数学运算



-- 聚合函数:对结果集进行统计、分析的函数。在聚合函数中,值是null的记录不参与统计
select count(*) from tb_user;  -- 记录总数
select count(username) from tb_user;  -- 某一列的记录数
select count(distinct username) from tb_user;  -- 去重,重复的记录只算做一条

select max(age) from tb_user;
select min(age) from tb_user;

select sum(score) from tb_student;
select avg(score) from tb_student;

select first(username) from tb_user;  -- 该列的第一个值

select last(username) from tb_user;  -- 该列的最后一个值

select sum(score)avg(score) from tb_student;  -- 可一起使用



-- 其它常用函数,as不能省略
select if(gender,'男','女') as gender from tb_user;  -- 相当于三元运算符

select ifnull(money,0) as money from tb_user;  -- 如为空,返回设置的默认值



-- order by子句,结果集排序
select * from tb_user order by age;  -- 默认按升序(asc)排列
select * from tb_user order by age desc;  -- desc降序
select * from tb_user order by name,age desc;  -- 多个排序关键字,前面的关键字字段值相同时,使用后面的关键字排序



-- group by 子句,结果集分组
select * from tb_student group by dep;  -- 把dep相同的记录分为一组,返回的是分好的组,不是记录

select count(*from tb_student group by dep;  -- 统计每个系的学生人数。单独使用group by意义不大,一般搭配聚合函数使用,统计每组的数据
select avg(score) from tb_student group by class;  -- 统计每个班的平均分



-- having子句,一般和group by搭配使用,用来对分组进行过滤
select * from tb_student [where子句] group by class having class between 0 and 9; #查询[1,10]班的学生信息
-- group by后面不能使用where,且where子句中不能直接使用聚合函数,having用于弥补where的不足
-- group by以哪个字段进行分组,having就只能以哪个字段进行过滤,把不符合要求的组去掉



-- 分页,常见的分页方式有三种
-- 1、where限制区间,eg.where id>0 and where id<10
-- 2、limit
-- 3、返回全部记录,由客户端实现分页,在结果集可能很大的情况下不推荐使用,内存、时间开销大

-- limit 结果集分页。oracle是top
select * from tb_user [where子句] [order by子句] limit 10;  #只返回结果集的前10条记录
select * from tb_user [where子句] [order by子句] limit 9,19;  #只返回结果集的第[10,20]条记录。都+1,再取闭区间



-- 多个子句的书写、执行顺序
select ... from ... [where子句]  [group by子句]  [having子句]  [order by子句]  [limit子句]
-- 先执行select ... from ...  [where子句] ,将匹配的记录放到结果集中
-- 再group by对结果集中的记录进行分组
-- having对分组进行过滤,去掉不满足条件的分组
-- orderby排序
-- limit只取出结果集的某个区间,返回给客户端


-- 常用的
select ...  from ...  [where子句]  [group by子句]  [having子句]
select ...  from ...  [where子句]  [order by子句]  [limit子句]


-- 别名
select username as '用户名' from tb_user;   -- 字段别名,返回时用别名替换字段名
select tu.username from tb_user tu;  -- 表别名,常用于多表查询

 

多表查询

union 结果集合并

如果多个select分别查表,select取的字段数、字段名、字段类型相同,可以使用union把多个结果集合并为一个结果集。
一个select返回m条记录,另一个select返回n条记录,合并之后就是m+n条记录

-- 查询全校师生的id、name

-- union默认会去重,如果合并得到的结果集中有重复的记录,只保留一条,distinct可以缺省
select id,name from tb_student union [distinct] select id,name from tb_teacher;  

-- all,保留全部记录,不去重
select id,name from tb_student union all select id,name from tb_teacher;   

-- 如果要合并多个结果集,两两之间union连接
select语句1 union [distinct|all] select语句2 union [distinct|all] select语句3 ...

 

子查询

-- 在where中使用子查询
-- eg.有2张表,tb_dep 一条记录即一个系的信息,tb_student 一条记录即一个学生的信息,查询计算系所有学生的学号、姓名
select id,name from tb_student where dep_id=(select id from tb_dep where dep_name='计算机系'); 



-- 在having中使用子查询
-- eg. 查询大于平均分的学生成绩
select * from tb_score group by id having score>(select avg(score) from tb_score)-- group by 主键,按主键分组,一个分组就是一条记录,对分组的过滤就是对记录的过滤


-- where、having的过滤中有2个常用关键字:any、all
where xxx > any(子查询)  #大于任一个即可
where xxx > all(子查询)  #大于所有才行



-- 在from中使用子查询
select 列名 from (select子查询);  -- 把子查询的结果集作为一张临时表

select 列名 fromselect子查询)[别名] [子句]-- 临时表的使用方式和表名一样

 

join 连接查询

笛卡尔积

2个集合相乘,得到的是笛卡尔积

{A,B,C} * {a,b,c} = { (A,a)(A,b)(A,c)(B,a)(B,b)(B,c)(C,a)(C,b)(C,c) } 

即用一个集合的每个元素去乘另一个集合的每个元素

 

sql99 连接查询语法

select1中的列,2中的列  from1 [别名]  [连接类型] join2 [别名] on 连接条件

[where子句]

[group by子句]

[having子句]

[order by子句]

[limit子句]

sql 99的连接查询带有关键字join,称之为显式写法。在sql 99之前还有一个sql语法版本:sql 92,顾名思义,92年制定的标准。sql 92的连接查询不带join,也具有相同的功能,现在还能用,称之为隐式写法。

 

根据连接类型可以把连接查询分为4类

  • 交叉连接
  • 内连接:又分为等值连接、非等值连接、自连接
  • 外连接:又分为左外连接(左连接)、右外连接(右连接)、全外连接(全连接,mysql不支持,oracle支持)
  • 自然连接
     

假设tb_student有30条记录,tb_score有20条记录(10人因缺考、缓考等原因暂时没有成绩)

-- 交叉连接,得到的是笛卡尔积,基本不用
select st.*,sc.* from tb_student st cross join tb_score sc;
select * from tb_student cross join tb_score;  -- 可以用一个*表示多表的所有字段
-- 30*20=600,返回600条记录




-- 内连接,以少的为准(2张表中都要有)
select * from tb_student st [inner] join tb_score sc on st.id=sc.student_id;  -- join默认就是内连接,inner可以缺省
-- 只返回20条记录,成绩为空的10人不要了

-- on指定2张表的连接条件(关联关系),使用on对笛卡尔积中的记录进行筛选。如果是单张表的条件,比如 st.id>10,写在where中

-- 等值连接:on中使用等号进行筛选、判断
-- 非等值连接:on中使用>、>=、<、<=、between and...连接2张表(不使用等号)



-- 内连接的隐式写法
select * from tb_student st,tb_score sc where st.id=sc.student_id;  -- 在where中指定连接条件



-- 内连接之自连接
-- 顾名思义,自己连接自己进行查询。有时候表是关联到自身的,需要连接自身来查询
-- eg. 员工表,员工和直属上司都是员工,都在一张表里。查询员工信息及其直属上司的姓名,superior_id是直属上司的id
select te1.*,te2.name as superior_name from tb_employees te1 [inner] join tb_employees te2 where te1.superior_id=te2.id;
-- 都是同一张表,取不同的别名来区分




-- 外连接
-- 内连接以少的为准(作为主表),外连接可以指定以哪张表为准(作为主表),更灵活
select * from tb_student st left [outer] join tb_score sc on st.id=sc.student_id;
-- outer可以省略不写,left是左外连接,right是右外连接,full是全外连接(mysql不支持,oracle支持)

-- 左外连接以join左边的表为准(主表),右外连接以join右边的表为准,全连接是2张表的记录都保留(在另一张表中找不到对应|关联的记录都保留)。




-- 自然连接
-- 自然连接可以看做是一种特殊的等值连接,会自动把2张表中相同的列(列名、数据类型都要相同)作为连接条件
select * from tb_student natural join tb_score;
-- 比如两张表都有id字段,会自动添加连接条件 on 表1.id=表2.id




-- 多张表,写多个join就行
select1的字段,2的字段,3的字段 from1 [别名]
left join2 [别名] on1.id=2.id
left join3 [别名] on2.id=3.id
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章