表中数据的查询操作-多表查询

准备 导入数据

--班级表

create table if not exists class( 
id tinyint unsigned primary key auto_increment,
name varchar(20) not null,
`desc` varchar(255),

- 反引号(`)用于包裹字段名 desc ,因为 desc  是 SQL 保留字(常用于 ORDER BY  子句表示降序)。通过反引号包裹,可避免数据库将其识别为保留字而引发语法错误,确保字段名的合法性与唯一性。
createdAt timestamp default current_timestamp,
updatedAt timestamp default current_timestamp on update current_timestamp

- on update current_timestamp :当记录更新时,自动刷新

);


insert into class(name,`desc `)values('一班’,'火箭班);
insert into class (name,`desc`) values('二班’,‘平行班');
insert into class(name,`desc`)values('三班’,‘实验班”);
insert into class (name,`desc`)values('四班’,‘待定班');

create table if not exists student(--学生表
id int unsigned primary key auto_increment,
name varchar(20) not null,
age tinyint unsigned not null,
gender enum('男‘,’女’,‘保密’)default‘保密’,
class_id tinyint unsigned,
createdAt timestamp default current_timestamp,
updatedAt timestamp default current_timestamp on update current_timestamp,
foreign key(class_id) references class(id) on update cascade on delete set null

);

FOREIGN KEY(class_id)

含义:声明当前表的 `class_id` 字段为外键。

作用:该字段的值必须引用另一张表的某个字段。

`ON UPDATE CASCADE`  
含义:当父表的 `id` 被修改时,子表的 `class_id` 自动同步更新。

`ON DELETE SET NULL`  
含义:当父表的某条记录被删除时,子表中对应的 `class_id` 自动设为 `NULL`。


insert into student (name, age, gender, class_ id)values('张三',20,'男',1);
insert into student (name, age, gender, class_id)

values('李四’,19,‘女',1);

insert into student(name, age, gender, class_id)

values ('王五', 21,'女',2);
insert into student (name, age, gender, class_id)
values('赵六’,18,'女',2);
insert into student(name, age, gender, class_id)
values('孙七’,19,‘男',3);
insert into student(name,age,

gender,class_id)values ('周八',19,'男',3);
insert into student (name, age, gender)values('张三丰',15,'男');

直接查询
只需要在单表查询基础上增加一张表即可,返回的结果是多张表的表数据个数的乘积,会有冗余数

select* from student;
select * from class;
select* from student, class;

笛卡尔积(Cartesian Product)
-定义:多表查询时,若未指定连接条件,结果集是两表行数的乘积。
-示例:  
  - `student` 表有 3 行,`class` 表有 2 行 → `SELECT * FROM student, class` 返回 3×2=6 行。
- 问题:数据冗余,大部分结果无实际意义。


select * from student, class where student.class_id = class.id;

作用**:通过 `WHERE` 条件过滤冗余数据,仅保留关联记录。  
结果:仅返回 `student.class_id` 与 `class.id` 匹配的行。  

内连接查询(INNER JOIN或 JOIN)
内连接的查询结果和直接查询的结果是一样的

内连接(`INNER JOIN` 或 `JOIN`)用于从两个或多个表中仅返回满足连接条件的行。
select * from student;
select * from student join class;

未指定连接条件,会产生笛卡尔积(所有可能的组合),结果通常无意义。
select * from student join class on student.class_id = class.id;
-- select id, name from student join class on student.class_id =class.id;--报错

原因:`id` 和 `name` 可能同时存在于 `student` 和 `class` 表中,数据库无法区分。  
- 解决方法:显式指定列所属的表名或别名。  

正确写法:  

select student.id, class.name from student join class on student.class_id = class.id;
select stu.id, cls.name from student stu join class cls on stu.class_id = cls.id;
取别名

外连接查询

左外连接查询(LEFT OUTER JOIN或 LEFT JOIN)

左边的表是不看条件的,无论条件是否满足,都会返回左表中的所有数据

只有右边的表会看条件,对于右表,只有满足条件的,才会返回,如果不满足条件,右表的所有字段会用 `NULL` 填充。

select * from student left join class on student.class_id = class.id;

右外连接查询(RIGHT OUTER JOIN或 RIGHT JOIN)

右边的表是不看条件的,无论条件是否满足,都会返回右表中的所有数据

只有左边的表会看条件,对于左表,只有满足条件的,才会返回

select * from student right join class on student.class_id = class.id;
UNION查询
在纵向上将多张表的查询结果拼接起来返回
必须保证多张表查询的字段个数一致
select id,name from student union select id,name from class;

子查询
将一个查询语句查询的结果作为另一个查询语句的条件来使用
select class_id from student where id = 3;
select class_id from student where id >= 3;
select name from class where id =(select class_id from student where id = 3);
select name from class where id in (select class_id from student where id >= 3);

外层查询

将一个查询语句查询结果作为另一个查询语句的来使用

必须给子查询起别名

select name from class where id >= 2;

select * from (select name from class where id >= 2) t;

- 执行逻辑:
 
1. 先执行子查询  (select name from class where id >= 2) ,这一步与第一个语句相同,得到一个包含  name  列的临时结果集。
 
2. 必须给这个临时结果集起别名(这里是  t ),否则 SQL 引擎无法识别和引用它。
 
3. 外层查询  select * from t  表示从别名  t  的临时结果集中获取所有列(由于子查询只返回  name  列,因此实际只返回  name  列)。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值