【MySQL进阶】表的增删改查操作(CRUD)+(SQL执行顺序)

本文深入讲解SQL中的数据复制、聚合查询、分组查询、条件过滤、联合查询等高级技巧,并通过实例演示各种查询方法的应用。

1. 新增(复制数据)

语法

-- 字段名 == 列名 
-- 将表2的数据复制到表1中 
-- 两张表的结构要一样
insert into 表名1 [(列名,列名..)] select 字段名/列名 from 表名2

create table test_ (id int , name varchar(20));
insert into test_(id,name) select id,name from student;
  • 操作的两张表在结构上要一致,才能进行新增复制.
  • 上述操作即:将student表中的id,name内容复制到test_表中.

2. 查询 - 进阶

2.1 聚合查询

聚合函数:

函数
COUNT( [ DISTINCT ] expr)返回查询的数据的 数量
SUM( [ DISTINCT ] expr)返回查询到数据的 总和 ,不是数字没有意义,如:id = 1,id = 5,查询id的总和是 6;
AVG( [ DISTINCT ] expr)返回查询到的数据的 平均值,不是数字没有意义,如::id = 1,id = 5,查询id的平均值是3
MAX( [ DISTINCT ] expr)返回查询到的数据的 最大值,不是数字没有意义.
MIN( [ DISTINCT ] expr)返回查询到的数据的 最小值,不是数字没有意义.

语法:

select 函数(列名) from 表名;

案列:

有student表的数据如下:
在这里插入图片描述

count()

统计班级有多少同学:

在这里插入图片描述

统计班级的math有多少个,math为null不会计入结果

插入一个math和English都为null的数据到student表中

在这里插入图片描述

sum()

统计不及格 < 60 的数学总分 ,没有结果返回null

select sum(math) from student where math < 60;

avg()

统计平均总分

-- as 给查询出来的临时表列名 取个别名 没忘记吧?(前面的内容)
select avg(math+English) as 平均总分  from student;

max()和min()

-- 查询math最高分
select max(math) from student;
-- 查询math最低分
select min(math) from student;

2.2 group by

select中使用group by 子句可以对指定列进行分组查询.

需要满足:使用group by进行分组查询时,select 指定的字段必须是"分组依据字段",其他字段若想出现在select中则必须包含在聚合函数中.

语法

select 列名1,聚合函数名(列名2),..from 表名 group by 列名1,列名2...;

案例:

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

-- 建表
create table emp(
 	id int primary key auto_increment,
    name varchar(20) ,
    role varchar(20),
    salary numeric(11,2)
);
-- 指定列名插入数据
insert into emp (name ,role , salary) values
('小微','经理',6500),
('猪猪女孩','服务员',2000),
('云朵','咖啡师',5500),
('彩云','咖啡师',5000),
('本人','咖啡师',4800);
  • 查询每个角色的最高工资,最低工资,平均工资
-- 按角色 进行分组查询  
-- role是"分组依据的字段"
select role,max(salary),min(salary),avg(salary) from emp group by role;

在这里插入图片描述

2.3 having

group by 字句进行分组以后,需要对分组结果再进行条件过滤时,不能使用where 语句,而需要用having;

语法:

select 列名1,聚合函数名(列名2),..from 表名 group by 列名1,列名2...having 表达式..;
  • 查询平均工资低于5000的角色和他的平均工资
-- 查询完后,再进行筛选
-- 把平均工资大于5000 的全部排除到结果外
select role,max(salary),min(salary),avg(salary) from emp group by role having avg(salary) < 5000;

在这里插入图片描述

2.4 联合查询

实际开发中往往数据是来自不同的表,所有需要多表联合查询.多表查询是对多个表的数据进行取 笛卡尔积:

把表1的第一行和表2的第一行进行配对,再和表2的第二行配对.

表1的第二行和表2的第一行进行配对,再和表2的第二行配对.

也就是两个表的行数乘积

不过这些个个匹配的数据,有大部分是无意义的数据,所以需要进行筛选,也就是接下来需要学习到的.

select * from1,2;
-- 可以加条件 只查找 表1的id和name 对应的表2的math
select1.id,1.name,2.math from1,2 where1.id =2.student_ID;

在这里插入图片描述

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

准备数据:

-- 建表
-- 使用关键字作为列名需要:`列名`
create table classes (
 id INT PRIMARY KEY auto_increment,
 name VARCHAR(20),
 `desc` VARCHAR(100)
);
create table student(
    id int primary key auto_increment,
     name varchar(20),
    sn int unique,
    classes_id int,
    foreign key (classes_id) references classes(id)
);
create table course(
	id int primary key auto_increment,
    name varchar(20)
);
create table score(
	id int primary key auto_increment,
    score decimal(3,1),
    student_id int,
    course_id int,
    foreign key (student_id) references student(id),
     foreign key (course_id) references course(id)
);
-- 初始化数据
insert into classes(id,name,'desc') values
(1,'软件20级4班','学习c,java,数据库'),
(2,'计算机系19级1班','学习计算机原理');

insert into student (id,sn,name,classes_id) values
(3,'20200401','小飞','1'),
(4,'20200402','小花','1'),
(9,'20210206','肖京腾','2');

insert into course(name) values 
('java,c'),
('计算机原理'),
('数据库'),
('语文'),
('数学');

insert into score (score,student_id,course_id) values
-- 小飞
(80,3,1),(60,3,3),
-- 小花
(80,4,2);

2.4.1 内连接

语法:


select 字段 from1 别名1 [inner] join2 别名2 on 连接条件 and 其他条件;
-- 两者等同
select 字段 from1 别名1,2 别名2 where 连接条件 and 其他条件;

案例

查询"小飞"同学的成绩

//方法1 
select sco.score from student stu join score sco on stu.id = sco.student_id and stu.name = "小飞";
//方法2
select sco.score from student stu, score sco where stu.id=sco.student_id and
stu.name='小飞';

在这里插入图片描述

  • .是成员访问运算符
  • student join score 表示 上student和score 进行联合.可以多表联合,比如 student和score联合完 可以再 join course表;表示 student和score联合完成一个表后,这个结合表再和course联合.
  • 查询所有学生成绩,如果有学生成绩是null,是不会被查询出来的.

2.4.2 外连接

外连接分为左外连接[left]和右外连接[right] . 如果联合查询,需要左侧的表完全显示就要用到左连接,右则的表完全显示用右连接.

语法: 在join 前+ left / right

-- 把表1的内容全部显示出来,是null也会查询出来
select 字段名 from1 left join2 on 连接条件;
-- 把表2的内容全部显示出来,是null也会查询出来
select 字段名 from1 left join2 on 连接条件;

查询所有同学的成绩

在这里插入图片描述

在这里插入图片描述

查询学生表,成绩表,课程表 ,3张表的关联查询:

在这里插入图片描述

2.4.3 自连接

自连接:自己和自己进行迪尔卡积.就是把行转成列,SQL中无法针对行和行之间进行条件比较,但是有的需求,又需要进行行和行之间比较,这时候就可以使用自连接,把行转成列.

查询"数据库"和"java"成绩高的信息

  1. 先查询 分数表
    在这里插入图片描述

  2. 再查询 课程信息

在这里插入图片描述

这两张表进行对比,可以看出"java"要比"数据库"成绩高

  1. 进行分数表的自连接

在这里插入图片描述

很明显,报错信息显示,表名重复, 如果要进行一张表自连接,需要起个别名.

在这里插入图片描述

自连接也会产生大量的无效匹配数据,所以也需要指定连接条件,在这里我们需要指定每个同学和自己的"数据库","java"成绩进行比较.

在这里插入图片描述

"java"的课程id是1,"数据库"课程id是3.

此时就可以看出"java"和"数据库"的对应关系80 > 60.仔细看见表可以发现 有左3 右1 和 左1右3的排列组合,因为排列组合是把所有可能性都排列出来了.可以把符合条件的记录挑选出来.

在这里插入图片描述

这个时候就把符合条件的数据挑选出来了, 且没有重复数据.可以看出谁是 “java” > "数据库"的数据; 由于这里案例数据少,所有已经就剩下一条数据了,一般而言还需要进行最后一步分数比较.

最终把"java">"数据库"的数据给筛选出来:

在这里插入图片描述

以上是分步查找的,要显示学生及成绩信息,可以一条语句显示:

select stu.*,s1.score java,s1.score 数据库
from 
 	score s1,
 	join score s2 on s1.student_id = s2.student_id
 	join student stu on s1.student_id = stu.id
 	join course c1 on s1.course_id  = c1.id
 	join course c2 on s2.course_id = c2.id
 	and s1.score < s2.score
 	and c1.name = "java"
 	and c2.name = "数据库";

2.4.4 子查询

子查询是指嵌入到其他SQL语句中的select语句,也叫嵌套查询(套娃?)

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

查询与"小飞"同学的同班同学

-- 分步查询 不用子查询
-- 查询出来 小飞的班级id是 1
select classes_id from student where student.name = "小飞";

select name from student where classes_id = 1 and name != "小飞";
-- 实际上 子查询就是这两句合并了


-- 查询name="小飞"的结果,把这个结果作为外面条件
--wehre classes_id = 结果
select * from student where classes_id = (select classes_id from student where name = "小飞");

classes_id =的 后面的子查询必须只返回一条记录,此时才可以写作 =,否则错误!

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

查询"数学"或"语文"课程的成绩信息

  1. [NOT] IN关键字
-- 1.查询课程id  数学的 = 5 语文的id= 4
select id from course where name = "数学" or name = "语文";
-- 2.查询成绩
select * from score where course_id = 5 or course_id = 4;

-- 使用in关键字 一步到位
select * from score where course_id in (select id from course where name = "数学" or name = "语文");

in查询的结果是放入内存中, 如果查询结果太大,内存就放不下,in就用不了,这时候就需要exists代替,其实如果查询结果太大,最好还是分步来查询

  1. [NoT] Exists 关键字 (可读性差,执行效率低)
select * from score where exists (select score.id from course where(name = '数学' or name = '语文') and course.id = score.course_id);

2.4.5 合并查询

本质是把两个查询结果合并成一个;并且两个结果的列相同,列名相同,类型相同,才能合并.

  • union 操作符

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

查询id小于3,或者名字为"语文"的课程

-- 使用unio
select * from course where id < 3 union 
select * from course where name = "语文";
-- 使用 or
select * from course where id < 3 or name = "语文";
  • union all

    该操作不会去掉重复行.

select * from course where id < 3 union all
select * from course where name = "语文";

3 SQL的执行顺序(where…)

在这里插入图片描述

<think>好的,用户想了解如何使用Java和Vue实现学生后台管理系统的增删改查功能。我需要理清整个系统的架构,然后分步骤讲解前后端的实现。 首,系统应该采用前后端分离的模式,前端用Vue,后端用Java的Spring Boot框架。这样分开开发,结构清晰,也便于维护。用户可能对技术选型不太清楚,需要简单说明为什么选择这些技术,比如Spring Boot的便捷性和Vue的响应式特性。 接下来是数据库设计。学生管理系统最基本的应该是学生,包含ID、姓名、性别、年龄等字段。需要给出建语句,并说明主键和字段类型。用户可能需要具体的SQL例子,所以得写出CREATE TABLE语句,并解释每个字段的作用。 然后是后端部分。使用Spring Boot搭建RESTful API,按照MVC模式分层。需要创建实体类(Entity)、数据访问层(Repository)、服务层(Service)和控制器(Controller)。这里要分别说明每个层的作用,比如Repository继承JpaRepository实现CRUD操作,Service处理业务逻辑,Controller暴露API接口。用户可能对注解如@RestController、@GetMapping不太熟悉,需要简要解释。 对于每个API接口,增删改查分别对应POST、DELETE、PUT、GET方法。要给出具体的URL和示例代码,比如添加学生用POST /api/students,参数用@RequestBody接收。同时,需要处理异常,比如学生不存在时返回404状态码。这里可能需要提醒用户注意异常处理的必要性,保证系统的健壮性。 前端部分使用Vue3和Element Plus构建界面。需要创建学生列页面,展示格,并带有添加、编辑、删除的按钮。使用axios与后端API通信。用户可能对Vue3的组合式API不熟悉,需要示例代码展示如何引入axios,定义响应式数据,并在生命周期钩子中获取数据。 组件方面,添加和编辑可以共用一个弹窗单组件,通过v-model绑定数据。需要说明如何触发弹窗显示,单验证的逻辑,以及提交时调用API的方法。用户可能需要知道如何处理单验证,所以得提到Element Plus的单验证规则配置。 前后端联调时,跨域问题可能会阻碍通信。需要提醒用户在Spring Boot中配置CORS,允许前端应用的域名和端口。此外,接口测试可以用Postman或Swagger,确保后端API正确无误后再对接前端。 数据展示方面,Vue格通过v-for循环渲染数据,同时处理分页可能需要后端支持分页查询,Spring Data JPA的Pageable可以很方便地实现分页,前端传递页码和每页数量参数。用户可能想实现分页功能,所以需要提到如何使用Element Plus的分页组件,并与后端API结合。 最后,部署方面需要简单说明,比如前端打包成静态文件部署到Nginx,后端打包成JAR运行。用户可能需要知道基本的部署步骤,但具体细节可能超出当前问题范围,所以可以简要带过,或建议查阅相关文档。 总结下来,我需要将整个实现过程分成数据库设计、后端实现、前端实现、联调测试几个部分,每部分给出关键代码示例和注意事项。确保用户能够按照步骤逐步搭建系统,同时理解各部分的作用和交互方式。遇到可能的坑,如跨域、单验证、异常处理,需要特别指出解决方案。</think>我将分步骤为您讲解Java+Vue实现学生管理系统的技术方案: 一、系统架构设计 $$系统架构图$$ 前端:Vue3 + Element Plus + Axios 后端:Spring Boot + MyBatis Plus + MySQL 接口规范:RESTful API 二、数据库设计(MySQL示例) ```sql CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, gender TINYINT COMMENT '0-女 1-男', age INT, email VARCHAR(100), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ); ``` 三、后端实现(Spring Boot) 1. 实体类 ```java @Data @TableName("student") public class Student { @TableId(type = IdType.AUTO) private Integer id; private String name; private Integer gender; private Integer age; private String email; private Date createTime; } ``` 2. Controller层示例 ```java @RestController @RequestMapping("/api/students") public class StudentController { @Autowired private StudentService studentService; // 查询 @GetMapping public Result list(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size) { Page<Student> pageInfo = studentService.page(new Page<>(page, size)); return Result.success(pageInfo); } // 添加学生 @PostMapping public Result add(@RequestBody Student student) { studentService.save(student); return Result.success(student.getId()); } } ``` 四、前端实现(Vue3 + Element Plus) 1. 学生列组件 ```vue <template> <el-table :data="studentList" style="width: 100%"> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="gender" label="性别"> <template #default="{row}"> {{ row.gender === 1 ? '男' : '女' }} </template> </el-table-column> <el-table-column label="操作"> <template #default="{row}"> <el-button @click="handleEdit(row)">编辑</el-button> <el-button type="danger" @click="handleDelete(row.id)">删除</el-button> </template> </el-table-column> </el-table> </template> <script setup> import { ref, onMounted } from 'vue' import axios from '@/utils/request' const studentList = ref([]) // 加载数据 const loadData = async () => { const res = await axios.get('/api/students') studentList.value = res.data.records } // 删除操作 const handleDelete = async (id) => { await axios.delete(`/api/students/${id}`) ElMessage.success('删除成功') loadData() } onMounted(() => { loadData() }) </script> ``` 五、关键技术点 1. 前后端交互:使用Axios封装请求拦截器,统一处理错误 2. 分页实现:后端使用MyBatis Plus分页插件,前端使用Element Plus分页组件 3. 单验证:Element Plus单规则校验 + 后端@Valid注解双重验证 4. 跨域处理:Spring Boot通过@CrossOrigin或配置CorsFilter 5. 异常处理:全局异常处理器@ControllerAdvice统一返回错误格式 六、部署流程 1. 后端打包:mvn clean package生成jar文件 2. 前端打包:npm run build生成dist目录 3. 使用Nginx配置反向代理: ```nginx server { listen 80; server_name yourdomain.com; location /api { proxy_pass http://localhost:8080; } location / { root /path/to/dist; index index.html; } } ``` 建议开发顺序: 1. 完成后端基础CRUD接口开发 2. 使用Postman测试接口可用性 3. 开发前端基础列展示功能 4. 逐步添加搜索、分页、单验证等进阶功能 5. 最后进行样式优化和性能优化 常见问题解决方案: 1. 跨域问题:检查CORS配置和Nginx代理设置 2. 时区问题:MySQL和服务器时区保持统一 3. 数据更新不同步:Vue使用key属性强制刷新组件 4. 单提交失败:检查Content-Type是否为application/json 该方案可实现基本的学生信息管理功能,实际开发中还需根据需求添加权限控制、文件上传、日志记录等模块。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bushi橙子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值