MySQL 约束特殊查询

news2025/1/10 21:00:59

MySQL 约束&特殊查询

文章目录

  • MySQL 约束&特殊查询
    • 1. 数据库约束
      • 1.1 约束类型
      • 1.2 NULL约束
      • 1.3 NUIQUE:唯一约束
      • 1.4 DEFAULT:默认值约束
      • 1.5 PRIMARY KEY:主键约束
      • 1.6 FOREIGN KEY:外键约束
      • 1.7 CHECK约束
    • 2. 表的关系
      • 2.1 一对一
      • 2.2 一对多
      • 2.3 多对多
    • 3. 特殊新增
    • 4. 查询
      • 4.1 聚合查询
        • 4.1.1 聚合函数
        • 4.1.2 GROUP BY 子句
        • 4.1.3 HAVING
      • 4.2 联合查询
        • 4.2.1 初始化
        • 4.2.2 操作步骤
        • 4.2.3 内连接
        • 4.2.4 外连接
        • 4.2.5 自连接
        • 4.2.6 合并查询

1. 数据库约束

1.1 约束类型

NOT NULL: 指示某列不能存储NULL值

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

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

PRIMARY KEY:确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录

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

CHECK:保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句

1.2 NULL约束

创建表时,可以指定某列不为空:

-- 设置学生表结构
CREATE TABLE student_5 (
	id INT NOT NULL,
	sn INT,
	name VARCHAR(20), 
	qq_mail VARCHAR(20)
);

在这里插入图片描述

1.3 NUIQUE:唯一约束

指定sn列中的值唯一且不重复的:

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

在这里插入图片描述

1.4 DEFAULT:默认值约束

指定插入数据时,name列为空,默认值为unknow

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

在这里插入图片描述

1.5 PRIMARY KEY:主键约束

指定id列为主键:

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

在这里插入图片描述

primary key 一般用于主要的字段,如id序号

对于整数类型的主键,常配搭自增长auto_increment来使用。插入数据对于字段不给值时,使用最大值+1

-- 主键是 NOT NULL 和 UNIQUE 的结合,可以不用 NOT NULL
id INT PRIMARY KEY auto_increment

1.6 FOREIGN KEY:外键约束

外键用于关联其他表主键唯一值

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

案例:

  • 创建班级表classes,id为主键

    -- 创建班级表,有使用MySQL关键字作为字段时,需要使用``来标识
    CREATE TABLE classes_5 (
    	id INT PRIMARY KEY auto_increment,
    	name VARCHAR(20),
    	`desc` VARCHAR(100)
    );
    

    在这里插入图片描述

  • 创建学生表student,一个学生对于一个班级,一个班级对应多个学生。使用id为主键,class_id为外键,关联班级表id

    DROP TABLE IF EXISTS student_5;
    CREATE TABLE student (
    	id INT NOT NULL PRIMARY KEY auto_increment,
    	sn INT UNIQUE,
    	name VARCHAR(20) DEFAULT '无名氏',
    	qq_mail VARCHAR(20),
        classes_id int,
       	FOREIGN KEY (classes_id) REFERENCES classes_5(id)
    );
    

    在这里插入图片描述

1.7 CHECK约束

MySQL使用时不报错,但忽略该约束(这个约束的使用率不高)

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

在这里插入图片描述

2. 表的关系

2.1 一对一

在这里插入图片描述

-- 一个人只能对应一张身份证,即两个表的id要相同
create table person (
    person_id int primary key, name varchar(20)
);
create table id_card (
    person_id int primary key, 
    name varchar(20),
    birthday datetime,
    address varchar(30),
    foreign key (person_id) references person(person_id)
);

在这里插入图片描述

2.2 一对多

在这里插入图片描述

-- 一个班级可以有多个学生(即能有不同的学生id),所以要为学生设置一个class_id来和class中的id匹配
 create table classes (id int primary key, class_name varchar(20));
 create table student (
     student_id int primary key, 
     name varchar(20), 
     class_id int, 
     foreign key (class_id) references classes(id)
);

在这里插入图片描述

2.3 多对多

在这里插入图片描述

-- 一个课程中间表(考试成绩表)既要和学生对应,也要和课程对应
create table course (course_id int primary key, course_name varchar(20));
create table score (
    id int primary key,
    score int, 
    student_id int,
    course_id int,
    foreign key (student_id) references student(student_id),
    foreign key (course_id) references course(course_id)
);

在这里插入图片描述

3. 特殊新增

我们可以将查询到的结果插入到新的表中

语法:

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

案例:创建一张学生用户表,设计有id学号 name姓名, 年龄age的字段,需要把已有的学生数据复制进来,刚创建且没有被复制赋值的字段为NULL

-- 给学生表插入数据
-- 因为学生表的id已经链接了班级表的id,所以需要先给班级表赋值才能给学生表插入数据
-- (且插入学生表的班级id必须是班级表里能够对应上的)
insert into classes values (707, '计科七班'), (808, '软工八班');
insert into student values (101, '张三', 707), (201, '里斯', 808);

-- 将学生表中能够赋值的数据复制到学生用户表中
insert into test_user (id, name) select student_id, name from student;

在这里插入图片描述

在这里插入图片描述

4. 查询

4.1 聚合查询

4.1.1 聚合函数

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

函数说明
COUNT([DISTINCT] expr)返回查询到的数据的 数量
SUM([DISTINCT] expr)返回查询到的数据的 总和,不是数字没有意义
AVG([DISTINCT] expr)返回查询到的数据的 平均值,不是数字没有意义
MAX([DISTINCT] expr)返回查询到的数据的 最大值,不是数字没有意义
MIN([DISTINCT] expr)返回查询到的数据的 最小值,不是数字没有意义
  • COUNT

    -- 统计班级共有多少同学
    SELECT COUNT(*) FROM student;
    
    -- 统计班级存在的学号一共有几个
    SELECT COUNT(class_id) FROM student;
    

    在这里插入图片描述

    注:当查询结果带有null值时,非count(*)其它count()查询不会将null值的记录计入数据

    insert into student(student_id, name) values (125, '小力');
    select count(class_id) 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

    -- 返回英语最低分
    select min(english) from exam_result;
    
    -- 返回 > 60分 的英语最低分
    select min(english) from exam_result where english > 60;
    

    在这里插入图片描述

4.1.2 GROUP BY 子句

SELECT中使用GROUP BY 子句可以对指定列进行分组查询

条件:使用GROUP BY 进行分组查询时,SELECT指定的字段必须是“分组依据字段”,其它字段若想出现在SELECT中则必须包含在聚合函数中

案例:

  • 准备测试表及数据:职员表,有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)
    );
    

    在这里插入图片描述

  • 查询每个角色的最高工资、最低工资和平均工资

    select role, max(salary), min(salary), avg(salary) from emp group by role;
    

    在这里插入图片描述

4.1.3 HAVING

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

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

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

    在这里插入图片描述

4.2 联合查询

4.2.1 初始化

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

在这里插入图片描述

在这里我们先初始化测试数据:

drop table if exists classes;
drop table if exists student;
drop table if exists course;
drop table if exists score;

create table classes (id int primary key auto_increment, name varchar(20), `desc` varchar(100));

create table student (id int primary key auto_increment, sn varchar(20),  name varchar(20), qq_mail varchar(20) , classes_id int);

create table course(id int primary key auto_increment, name varchar(20));

create table score(score decimal(3, 1), student_id int, course_id int);

insert into classes(name, `desc`) valu
	('22级计科7班', '学习了计算机原理、Python、C、Java、数据结构和算法'),
	('19级汉语言3班', '学习了中国传统文学'),
	('23级自动化2班', '学习了机械自动化、单片机')insert into student(sn, name, qq_mail, classes_id) values
('09982','黑旋风李逵','xuanfeng@qq.com',1),
('00835','菩提老祖',null,1),
('00391','白素贞',null,1),
('00031','许仙','xuxian@qq.com',1),
('00054','不想毕业',null,1),
('51234','好好说话','say@qq.com',2),
('83223','tellme',null,2),
('09527','老外学中文','foreigner@qq.com',2);

insert into course(name) values
('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');

insert into score(score, student_id, course_id) values
-- 黑旋风李逵
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
-- 菩提老祖
(60, 2, 1),(59.5, 2, 5),
-- 白素贞
(33, 3, 1),(68, 3, 3),(99, 3, 5),
-- 许仙
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
-- 不想毕业
(81, 5, 1),(37, 5, 5),
-- 好好说话
(56, 6, 2),(43, 6, 4),(79, 6, 6),
-- tellme
(80, 7, 2),(92, 7, 6);

在这里插入图片描述

4.2.2 操作步骤

在进行多表查询时,一般可分为以下四个步骤:

  1. 先进行笛卡尔积
  2. 再指定连接条件
  3. 其次可指定其它条件
  4. 最后针对列进行精简

案例:查询"许仙"同学的成绩

  • 笛卡尔积

    -- 指定两个有关联的表进行笛卡尔积
    select * from student, score;
    

    在这里插入图片描述

  • 指定连接条件

    -- 指定连接条件精简结果(可以通过点【表名.】调用字段)
    select * from student, score where student.id = score.student_id; 
    

    在这里插入图片描述

  • 再根据需求补充其它条件

    -- 找许仙的成绩
    select * from student, score where student.id = score.student_id and student.name = '许仙';
    

    在这里插入图片描述

  • 针对上面的最后再进行精简

    select student.name, score.score from student, score where student.id = score.student_id and student.name = '许仙';
    

    在这里插入图片描述

注:整个过程也可以总结为一句sql语句来调用

select student.name, score.score from student, score where student.id = score.student_id and student.name = '许仙';
4.2.3 内连接

其操作步骤与上述步骤相同,只是语法不同而已

语法:

select 字段 from1 别名 join2 别名 on 连接条件 and 其它条件;

--也可以这样做
select 字段 from1 别名1,2 别名2 where 连接条件 and 其它条件;

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

案例:

  • 查询"许仙"同学的成绩

    select stu.name, sco.score from student as stu join score as sco on stu.id = sco.student_id and stu.name = '许仙';
    
    select stu.name, sco.score from student as stu, score as sco where stu.id = sco.student_id and stu.name = '许仙';
    

    在这里插入图片描述

  • 查询所有同学的总成绩,及同学的个人信息

    -- 成绩表对学生表是多对一关系,查询总成绩是根据成绩表的同学id来进行分组的
    select stu.sn, stu.name, stu.qq_mail, sum(sco.score) from student as stu join score as sco on stu.id = sco.student_id group by sco.student_id;
    

    在这里插入图片描述

  • 查询所有同学的成绩,及同学的个人信息

    这里需要将三张表进行笛卡尔积,先找到表之间的关联关系,将有关联的两张表进行笛卡尔积,再将得到的结果和另一张表计算笛卡尔积

    -- student 和score 计算笛卡尔积
    select stu.id, stu.sn, stu.name, stu.qq_mail, sco.score, sco.course_id, cou.name from student as stu join score as sco on stu.id = sco.student_id join course as cou on sco.course_id = cou.id order by stu.id;
    

    在这里插入图片描述

4.2.4 外连接

外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就是是右外连接

语法:

-- 左外连接,表1完全显示
select 字段名 from 表名1 left join 表满2 on 连接条件;

-- 右外连接,表2完全显示
select 字段名 from 表名1 right join 表满2 on 连接条件;

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

-- "老外学中文"同学 没有考试成绩,也显示出来了
select * from student as stu left join score as sco on stu.id = sco.student_id;
-- 对应的右外连接
select * from student as stu right join score as sco on stu.id = sco.student_id;

在这里插入图片描述

在这里插入图片描述

4.2.5 自连接

自连接是指在同一张表上连接自身进行查询

案例: 显示所有"计算机原理"成绩比"Java"成绩高的成绩信息

-- 先查询"计算机原理"和"Java"课程的id
select id, name from course where name = 'Java' or name = '计算机原理';

-- 再查询成绩表中,"计算机原理"成绩比"Java"成绩好的信息
select s1.* from score as s1, score as s2 where s1.student_id = s2.student_id and s1.score < s2.score and s1.course_id = 1 and s2.course_id = 3;

在这里插入图片描述

4.2.6 合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符unionunion all。使用unionunion all时,前后查询的结果集中,字段需要一致(union左右两侧sql可以是查询两个不同的表,而or不行)

  • union

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

    案例:查询id小于3,或者名字为"英文"的课程:

    select * from course where id < 3 union select * from course where name = '英文';
    

    在这里插入图片描述

  • union all

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

    案例:查询id小于3,或者名字为"Java"的课程

    -- union all的结果集中出现重复的数据Java
    select * from course where id < 3 union all select * from course where name = 'Java';
    

    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1199089.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EXCEL中将UTC时间戳转为日期格式(精确到秒)

UTC时间戳的格式通常是一个整数&#xff0c;表示从1970年1月1日00:00:00 UTC到当前时间的总秒数。它可以以秒或毫秒为单位表示。例如&#xff0c;如果当前时间是2023年3月17日 12:34:56 UTC&#xff0c;则对应的UTC时间戳为1679839496&#xff08;以秒为单位&#xff09;或1679…

【Spring】事务实现原理

在使用事务的时候需要添加EnableTransactionManagement注解来开启事务&#xff0c;Spring事务底层是通过AOP来实现的&#xff0c;所以启用事务后&#xff0c;同样会向容器中注入一个代理对象创建器&#xff0c;AOP使用的是AnnotationAwareAspectJAutoProxyCreator&#xff0c;事…

【阿里云】函数计算 X 通义千问快速部署

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

多孔对跨孔电磁波CT联合反演

多孔对跨孔电磁波CT联合反演 前言 针对单一孔对跨孔电磁波CT反演数据拼接剖面不连续&#xff0c;相邻钻孔间吸收系数差异大的问题&#xff0c;采用多孔对跨孔电磁波CT联合反演。 1、多孔对数据拼接 将所有单一剖面连接为多孔剖面&#xff0c;以‘东大北大’的原则编号。 …

CorelDRAW2023中文免费版矢量图设计软件

设计工作经验丰富的人一定对比过多种设计软件&#xff0c;在对众多矢量图设计软件进行对比之后&#xff0c;多数资深设计师认为CorelDRAW的专业性、便捷性以及兼容性的综合表现更好&#xff0c;而且软件还配置了海量艺术笔&#xff0c;这让工作成果更为出众&#xff0c;因此更愿…

linux安装并配置git连接github

git安装 sudo apt-get install git git信息配置 git config --global uer.name "yourname" git config --global user.email "youremail" 其中&#xff0c;yourname是你在github上配置的用户名&#xff0c;youremail是你在github上设置的邮箱 查看git…

如何让useEffet支持async/await

前言 刚开始学react写过类似下面的代码&#xff0c;就是想直接在useEffect中使用async/await。然后浏览器就会报错如下图&#xff1a; useEffect(async () > {const res await Promise.resolve({ code: 200, mes: });}, [])报错的意思&#xff1a; useEffect 期望接受一…

FM模型与POLY2模型

两个核心细节 掌握FM&#xff0c;有两个细节需要注意&#xff1a;参数量级的变化和时间复杂度的变化。 首先对于参数量级&#xff0c;由线性模型到多项式模型到FM模型参数量级变化为&#xff1a; n–>n*n–>kn (k<<n) 其次是由原始FM公式到化简之后的FM公式复杂…

ArduPilot开源代码之Aocoda-RC F405V2 Mark4 7“ PNP适配

ArduPilot开源代码之Aocoda-RC F405V2 Mark4 10"适配 1. 源由2. 安装2.1 Installing Ground Station (GCS) software2.2 Autopilot System Assembly Instructions2.3 Loading Firmware2.4 Connect Mission Planner to AutoPilot 3. 配置3.1 Basic System Overview3.2 Fram…

头歌答案--数据持久化(非数据库)

目录 ​编辑 数据持久化&#xff08;非数据库&#xff09; 第1关&#xff1a;数据持久化&#xff08;非数据库&#xff09; 任务描述 多线程、多进程爬虫 第1关&#xff1a;多线程、多进程爬虫 任务描述 Scrapy爬虫基础 任务描述 MySQL数据库编程 第1关&#xff1a;…

如何删除英文键盘ENG

1.打开设置&#xff1a;时间和语言2.选择语言&#xff0c;查看首选列表&#xff0c;如果有多种语言&#xff0c;删除其他的语言就可以&#xff0c;如果只有中文&#xff0c;需要点击添加语言 3.选择安装的语言 这个时候点击英语&#xff0c;在选项中就可以看到它的默认键盘&…

盘点双11!阿里妈妈助这些品牌短视频赢增长!

刚刚&#xff01;一年一度的双11落下帷幕&#xff0c;很多新变化值得回味。 尽管天气在变凉&#xff0c;但市场出现了逐渐回暖的迹象。在此背景下&#xff0c;大量商家特别关心如何在双11打一场漂亮的胜仗。 卖方如何行动&#xff0c;关键在于买方的变化。在阿里妈妈发布的《…

小H靶场学习笔记:DC-2

DC-2 Created: November 10, 2023 3:01 PM Tags: WordPress, git提权, rbash逃逸 Owner: 只会摸鱼 靶场过程 信息收集 扫描存活主机&#xff0c;找到靶机ip&#xff1a;192.168.199.131&#xff08;本机是192.168.199.129&#xff09; 扫描端口开放协议 发现有80端口和77…

通过 Elasticsearch 和 Go 使用混合搜索进行地鼠狩猎

作者&#xff1a;CARLY RICHMOND&#xff0c;LAURENT SAINT-FLIX 就像动物和编程语言一样&#xff0c;搜索也经历了不同实践的演变&#xff0c;很难在其中做出选择。 在本系列的最后一篇博客中&#xff0c;Carly Richmond 和 Laurent Saint-Flix 将关键字搜索和向量搜索结合起…

第23章(下)_索引原理剖析

文章目录 索引实现索引存储B树为什么 MySQL InnoDB 选择 B 树作为索引的数据结构&#xff1f;B 树层高问题关于自增id最左匹配原则覆盖索引索引下推innodb体系结构Buffer poolchange buffer 总结 索引实现 索引存储 innodb 由段、区、页组成。段分为数据段、索引段、回滚段等…

手把手带你创建一个自己的GPTs

大家好&#xff0c;我是五竹。 最近GPT又进行了大升级&#xff0c;这一下又甩了国内AI几条街&#xff0c;具体更新了哪些内容之前的一篇文章中其实已经说过了&#xff1a;ChatGPT 王炸升级&#xff01;更强版 GPT-4 上线&#xff01; 其中最重要的一点就是支持自定义GPT&…

【博士每天一篇文献-算法】Imposing Connectome-Derived Topology on an Echo State Network

阅读时间&#xff1a;2023-11-5 1 介绍 年份&#xff1a;2022 作者&#xff1a;Jacob Morra, Mark Daley 西部大学 期刊&#xff1a;2022 International Joint Conference on Neural Networks (IJCNN) 引用量&#xff1a;3 研究了果蝇连接图的拓扑结构对混沌时间序列预测中回…

IP-guard Webserver view 远程命令执行漏洞【2023最新漏洞】

IP-guard Webserver view 远程命令执行漏洞【2023最新漏洞】 一、漏洞描述二、漏洞影响三、漏洞危害四、FOFA语句五、漏洞复现1、手动复现yaml pocburp发包 2、自动化复现小龙POC检测工具下载地址 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传…

代码随想录算法训练营第18天|513. 找树左下角的值 112. 路径总和 113.路径总和ii 106.从中序与后序遍历序列构造二叉树

JAVA代码编写 513. 找树左下角的值 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7提示: 二叉树的节点个…

Vue.js 学习总结(3)—— vite 打包图片时报错 Rollup failed to resolve import...

问题 图片依赖&#xff1a; Vite 打包前端项目时图片无法引入&#xff0c;报如下错误&#xff1a; ERROR [vite]: Rollup failed to resolve import "%7BlibeiDanmuKongmu%7D" from "D:/java/workspace/jeecgboot-vue3/src/views/funeral/tombInfo/area.vue?…