SQL 连接查询技术笔记

一、连接查询介绍

属于 DQL 查询,用于多张表联合查询数据 。

MySQL 中使用 join 实现多表连接,分为三类:

  • inner join:内连接
  • left join:左连接
  • right join:右连接

数据准备

sql 复制代码
-- 创建数据库
create database db_test2;
use db_test2;

-- 班级表
create table classes(
    class_id int primary key auto_increment,
    class_name varchar(40) not null unique,
    class_remark varchar(200)
);

-- 学生表
create table students(
    stu_num char(8) primary key,
    stu_name varchar(20) not null,
    stu_gender char(2) not null,
    stu_age int not null,
    cid int
);

-- 班级测试数据
insert into classes(class_name,class_remark) values('Java2204','...');
insert into classes(class_name,class_remark) values('Java2205','...');
insert into classes(class_name,class_remark) values('Java2206','...');
insert into classes(class_name,class_remark) values('Python2205','...');

-- 学生测试数据
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('20220101','张三','男',20,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('20220102','李四','女',20,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('20220103','王五','男',20,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('20220104','赵柳','女',20,2);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid) values('20220105','孙七','男',20,2);
-- 无班级的学生,cid为null
insert into students(stu_num,stu_name,stu_gender,stu_age) values('20220106','小红','女',20);
insert into students(stu_num,stu_name,stu_gender,stu_age) values('20220107','小明','男',20);

二、内连接 inner join

只返回两张表匹配条件成立的数据,两边没有匹配的记录不会出现在结果中。

笛卡尔积

不写匹配条件时,A表每条记录和B表每条记录全部互相组合,总条数 = A表条数 × B表条数,大部分数据无业务意义,必须加匹配条件过滤。

语法

sql 复制代码
-- on:连接匹配条件,推荐写法,先匹配再组合数据,效率高
select * from students inner join classes on students.cid = classes.class_id;

-- where:先生成笛卡尔积,再过滤,效率低,不推荐
select * from students inner join classes where students.cid = classes.class_id;

结果说明:小红、小明(无班级),Java2206、Python2205(无学生)不会被查询出来。


三、左连接 left join

以左边表为基准,左表所有记录全部展示 ;右表匹配到就显示对应数据,没有匹配则字段填充 null。

语法

sql 复制代码
select * from students left join classes on students.cid = classes.class_id;

结果说明:全部学生都会显示;小红、小明班级相关字段全部为null。


四、右连接 right join

以右边表为基准,右表所有记录全部展示 ;左表匹配到就显示对应数据,没有匹配则字段填充 null。

语法

sql 复制代码
select * from students right join classes on students.cid = classes.class_id;

结果说明:全部班级都会显示;Java2206、Python2205对应的学生字段全部为null。


五、数据表别名

多表查询,表名较长时,可以给表设置别名简化书写;

多张表存在同名字段,必须使用 表名.字段名 区分。

sql 复制代码
-- 给表设置别名 s、c
select s.stu_name, c.class_name 
from students s 
inner join classes c 
on s.cid = c.class_id;

⚠️ 核心要点总结

连接类型 特点
inner join 只返回两边互相匹配的数据
left join 保留左表全部数据,右表无匹配填null
right join 保留右表全部数据,左表无匹配填null
  1. 连接匹配条件使用 on,不要用where做连接匹配;where用于连接完成之后再过滤结果。
  2. 多表字段重名,必须通过 表别名.字段名 指定字段来源。
  3. 笛卡尔积会产生大量无效数据,多表连接一定要写on匹配条件。
相关推荐
Nturmoils4 小时前
GROUP BY 先别想当然,查汇总前把规则跑清楚
数据库
最笨的羊羊4 小时前
Oceanbase数据库系列之:向量数据库核心知识
数据库·oceanbase
fish_xk4 小时前
mysql中的表的约束
数据库·mysql
谢亮_vipxieliang4 小时前
Go Channel 高级模式——从底层原理到扇出扇入实战
java·数据库·golang
一隅论数智5 小时前
OWL(Web Ontology Language)介绍与使用举例(二)
大数据·经验分享·笔记·学习·自然语言处理·学习方法·政务
ggaofeng6 小时前
自己编写邮件服务器和客户端
数据库
java1234_小锋6 小时前
【技术专题】Mysql8 数据库 - Mysql8 添加,更新,删除数据
数据库·mysql
PaperData6 小时前
2015-2024年各省绿色贸易数据
数据库
小羊没烦恼!6 小时前
系统内部模块(子系统)之间的耦合以及模块(子系统)划分
java·开发语言·前端·数据库·算法·c#
麦壳饼6 小时前
深入探讨:SonnetDB 的文件格式与存储布局
数据库·sonnetdb