MySQL进阶用法

一、数据库的约束

1.1约束类型

NOT NULL-指示某列不可以存储NULL值

UNIQUE- 保证某列的每行必须有唯一的值

DEFAULT-规定没有给列赋值时的默认值

PRIMARY KEY- NOT NULL和UNIQUE的结合,确保某列有唯一标识,有助于更快找到某表记录

FOREIGN KEY-保证一个表的数据匹配另一个表的值的参照完整性

CHECK-保证列中的值符合指定要求

1.2NULL约束

创建表时,可以指定某列不为空:
DROP TABLE IF EXISTS student;
CREATE TABLE student(
    id INT NOT NULL,
    sn INT ,
    name VARCHAR(20),
    qq_email VARCHAR(20)
);

1.3 UNIQUE 唯一约束

--指定sn列是唯一的,不重复的
DROP TABLE IF EXISTS student;
CREATE TABLE student(
    id INT NOT NULL,
    sn INT UNIQUE,
    name VARCHAR(20),
    qq_mail VARCHAR(20)
);

1.4 DEFAULT 默认值约束

--重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TALBE student(
    id INT NOT NULL,
    sn INT UNIQUE,
    name VARCHAR(20) DEFAULT 'unkown',
    qq_mail VARCHAR(20)
);

1.5 PRIMARY KEY 主键约束

指定id列为主键
重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TALBE student(
    id INT  PRIMARY KEY AUTO_INCREMENT,
    sn INT UNIQUE,
    name VARCHAR(20) DEFAULT 'unkown',
    qq_mail VARCHAR(20)
);
AUTO_INCREMENT 自增,当插入数据对应字段不给值时,使用最大值+1
主键PRIMARY KEY是NOT NULL和UNIQUE 的结合,可以不同NOT NULL

1.6 FOREIGN KEY 外键约束

外键用于关联其他表的主键或者唯一键,语法:

foreign key (字段名) references 主表(列)

案例:

创建班级表classes,id为主键
--如果使用mysql关键字作为字段时,用''来标识
DROP TABLE IF EXISTS classes;
CREATE TABLE classes(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20),
'desc' VARCHAR(100));
创建学生表student,用id主键,classes_id为外键
DROP TABLE IF EXISTS student;
CREATE TABLE student(
    id INT PRIMARY KEY auto_increment,
    sn INT UNIQUE,
    name VARCHAR(20)DEFAULT 'unkown',
    qq_mail VARCHAR(20),
    classes_id INT,
    FOREIGN KEY(classes_id) REFERENCES classes(id)
);

1.7 CHECK 约束

DROP table if exists test_user;
create table test_user (
id int,
name varchar(20),
sex varchar(1),
check (sex ='男' or sex='女')
);

二、表的设计

三大范式: 一对一,一对多,多对多

一对一

一对多

 多对多

 他们之间的联系是通过外键进行连接

三、新增

插入查询结构

语法:INSERT INTO table_name [(column [, column ...])] SELECT ...

案例:创建一张用户表,设计有name姓名、email邮箱、sex性别、mobile手机号字段。需要把已有的学生数据复制进来,可以复制的字段为name、qq_mail

-- 创建用户表DROP TABLE IF EXISTS test_user;
CREATE TABLE test_user (
id INT primary key auto_increment,
name VARCHAR(20) comment '姓名',
age INT comment '年龄',
email VARCHAR(20) comment '邮箱',
sex varchar(1) comment '性别',
mobile varchar(20) comment '手机号');
-- 将学生表中的所有数据复制到用户表
insert into test_user(name, email) select name, qq_mail from student;

四、查询

4.1聚合查询

常见的统计总数,计算平局值等操作,可以使用聚合函数来实现,常见的聚合函数有:

函数

说明

COUNT([DISTINCT] expr)

返回查询到的数据的 数量

SUM([DISTINCT] expr)

返回查询到的数据的 总和,不是数字没有意义

AVG([DISTINCT] expr)

返回查询到的数据的 平均值,不是数字没有意义

MAX([DISTINCT] expr)

返回查询到的数据的 最大值,不是数字没有意义

MIN([DISTINCT] expr)

返回查询到的数据的 最小值,不是数字没有意义

案例:

*COUNT

统计班级共有多少同学
SELECT COUNT(*) FROM student;
SELECT COUNT(0) FROM student;
-- 统计班级收集的 qq_mail 有多少个,qq_mail 为 NULL 的数据不会计入结果
SELECT COUNT(qq_mail) FROM student;

*SUM

-- 统计数学成绩总分
SELECT SUM(math) FROM exam_result;
-- 不及格 < 60 的总分,没有结果,返回 NULL
SELECT SUM(math) FROM exam_result WHERE math < 60;

*AVG

--统计平均总分
SELECT AVG(chinese+math+english) 平均总分 FROM exam_result;

*MAX

--返回英语最高分
SELECT MAX(english) FROM exam_result;

*MIN

--返回》70分以上的数学最低分
SELECT MIN(math) FROM exam_result WHERE math>70;

4.2 GROUP BY子句

SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:使用 GROUP BY 进行分组查询时,SELECT 指定的字段必须是“分组依据字段”,其他字段若想出现在SELECT 中则必须包含在聚合函数中。

SELECT column1,sum(column2),.. from table group by column1,column3;

案例:准备测试表及数据:职员表,有id(主键)、name(姓名)、role(角色)、salary(薪水)

create table emp(
id int primary key auto_increment,
name varchar(20) not null,
role varchar(20) not null,
salary numeric(11,2)
);
insert into emp(name, role, salary) 
values('马云','服务员', 1000.20),
('马化腾','游戏陪玩', 2000.99),
('孙悟空','游戏角色', 999.11),
('猪无能','游戏角色', 333.5),
('沙和尚','游戏角色', 700.33),
('隔壁老王','董事长', 12000.66);
查询每个角色的最高工资、最低工资和平均工资
select role,max(salary),min(salary),avg(salary) 
from emp group by role;

4.3 HAVING语句

GROUP BY子句分组以后,需要对分组结果进行条件过滤时,不能使用WHERE 语句,需要使用HAVING

*显示平均工资低于1500的角色和它的平均工资

SELECT role,avg(salary) from emp group by role
having avg(salary)<1500;

4.4联合查询

实际开发中,数据来自不同的表,所以需要多边联合查询,多表查询是对多张表的数据取笛卡尔积

例如 a表                                b表                        笛卡尔积

   

注意:关联查询可以对关联表使用别名

下面的操作同时借用了不同表的数据,来进行总体操作

--添加新课程
INSERT INTO classes (name,'desc') values
("计算机科学与技术",'学习软硬件的原理');
--添加新学生
INSERT INTO student(sn,name,email,classes_id) values
('001','贝吉塔','xx@outlook.com',1);
--向课程里添加新课程名字
 INSERT INTO course (name) values
 ('java'),('c++'),('计算机组成原理');
 --插入贝吉塔同学的成绩
INSERT INTO score(score,student_id,course_id) values
(70.5,1,1);

4.5 内连接

语法:

select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;

select 字段 from 表1 别名1,表2,别名2 where 连接条件 and 其他条件 ;

案例:

.查询 贝吉塔同学的成绩
--将  student表和score表连接,并且两个都起了别名,方便输入
select sco.score from student stu  innner join score sco on stu.id=sco.student_id
and stu.name='贝吉塔';
或者
select sco.score from student stu,score sco where stu.id=sco.student_id and
stu.name='贝吉塔'

2.查询所有同学总成绩,以及个人信息
--成绩表对学生表多对1的关系,查询总成绩是根据成绩表的同学id进行分组
SELECT 
    stu.sn,
    stu.name,
    stu.email,
    sum(sco.score)
FROM
     student stu
     JOIN score sco ON stu.id=sco.student_id
GROUP BY
    sco.student_id;

4.6外连接

外连接分为左外连接和右外连接,如果联合查询,

左侧的表完全显示就是左外连接

右侧的表完全显示就是右外连接

语法:

--左外连接,表1完全显示

select 字段名 from 表名1 left join 表名2 on 连接条件;

--右外连接,表2完全显示

select 字段 from 表名1 right join 表名 2 on 连接条件 ;

案例:查询所有同学的成绩,及同学的个人信息,如果该同学没有成绩,也需要显示

-- “老外学中文”同学 没有考试成绩,也显示出来了
select * from student stu left join score sco on stu.id=sco.student_id;
-- 对应的右外连接为:
select * from score sco right join student stu on stu.id=sco.student_id;
-- 学生表、成绩表、课程表3张表关联查询
SELECT
stu.id,
stu.sn,
stu.NAME,
stu.qq_mail,
sco.score,
sco.course_id,
cou.NAME
FROM
student stu
LEFT JOIN score sco ON stu.id = sco.student_id
LEFT JOIN course cou ON sco.course_id = cou.id
ORDER BY
stu.id;

4.7自连接

自连接是同一张表连接自身去查询

案例:

显示所有“计算机原理”成绩比“Java”成绩高的成绩信息
--先查询'计算机组成原理’和‘java’课程的id
select id,name from course where name='java' or name='计算机原理';
--再查询成绩表中,‘计算机组成原理’成绩比‘java’成绩好的信息
-- 使用join on 语句来进行自连接查询
SELECT
s1.*
FROM
score s1
JOIN score s2 ON s1.student_id = s2.student_id
AND s1.score < s2.score
AND s1.course_id = 1
AND s2.course_id = 3;

4.8子查询

子查询就是嵌入在其他sql语句中的select语句,也叫嵌套查询

单行子查询:返回一行记录的子查询

查询与“不想毕业” 同学的同班同学

select * from student where classes_id=(select classes_id from student where

name='不想毕业');

多行子查询:返回多行记录的子查询

案例:

1.[NOT] IN 关键字

查询‘语文’或‘英文’课程的成绩信息
-- 使用IN
select * from score where course_id in (select id from course where
name='语文' or name='英文');
-- 使用 NOT IN
select * from score where course_id not in (select id from course where
name!='语文' and name!='英文');

2.[NOT] EXISTS关键字


-- 使用 EXISTS
select * from score sco where exists (select sco.id from course cou
where (name='语文' or name='英文') and cou.id = sco.course_id);
-- 使用 NOT EXISTS
select * from score sco where not exists (select sco.id from course cou
where (name!='语文' and name!='英文') and cou.id = sco.course_id);

from语句中使用子查询,子查询语句出现在from子句中,这里是把一个子查询当做一个临时表来使用

4.9合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致

*union 去重

该操作符用于取得两个结果集的并集,当操作该操作符时,会自动去掉结果集中的重复行

案例:

查询id小于3,或者名字为“英文”的课程:

select * from course where id<3
union
select * from course where name='英文';
-- 或者使用or来实现
select * from course where id<3 or name='英文';

*union all 不去重

该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行.

查询id小于3,或者名字为“Java”的课程
-- 可以看到结果集中出现重复数据Java
select * from course where id<3
union all
select * from course where name='英文';

五、内容重点总结

约束类型

说明

示例

NULL

约束

使用

NOT NULL

指定列不为空

name varchar(20) not null,

UNIQUE

唯一约束

指定列为唯一的、不重复的

name varchar(20) unique,

DEFAULT

默认值约束

指定列为空时的默认值

age int default 20,

主键约束

NOT NULL

UNIQUE

的结合

id int primary key,

外键约束

关联其他表的

主键

唯一键

foreign key (字段名) references 主表

(列)

CHECK

约束(了解)

保证列中的值符合指定的条件

check (sex ='男' or sex='女')

表的关系

1. 一对一:

2. 一对多

3. 多对多:需要创建中间表来映射两张表的关系

新增:

INSERT INTO table_name [(column [, column ...])] SELECT...

查询:

1. 聚合函数:

MAX、MIN、AVG、COUNT、SUM

2. 分组查询:

GROUP BY... HAVING ...

3. 内连接

select ... from 表1,表2 where 条件
-- inner可以缺省
select ... from 表1 join 表2 on 条件 where 其他条件

4.外连接:

select ... from 表1 left/right join 表2 on 条件 where 其他条件

5.自连接:

select ... from 表1,表1 where 条件

select ... from 表1 join 表1 on 条件

6.子查询:

-- 单行子查询
select ... from 表1 where 字段1 = (select ... from ...);
-- [NOT] IN
select ... from 表1 where 字段1 in (select ... from ...);
-- [NOT] EXISTS
select ... from 表1 where exists (select ... from ... where 条件);
-- 临时表:form子句中的子查询
select ... from 表1, (select ... from ...) as tmp where 条件

7.合并查询:

-- UNION:去除重复数据
select ... from ... where 条件
union
select ... from ... where 条件
-- UNION ALL:不去重
select ... from ... where 条件
union all
select ... from ... where 条件
-- 使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致

SQL查询中各个关键字的执行先后顺序:

from > on> join > where > group by > with > having >select > distinct > order by > limit

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值