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匹配条件
相关推荐
Databend1 小时前
从万亿级大模型到全线应用:Databend Cloud 助力头部 AI 企业构建全链路 Trace 数据管道
大数据·数据库·sql
尤乐娃子1 小时前
进入大厂(厂子大)实习Day11
前端·笔记·实习
MC皮蛋侠客1 小时前
SQLAlchemy 系列(十一):从 1.x 到 2.x——渐进迁移与数据访问层治理
数据库·python
1001101_QIA2 小时前
工控机网络配置
开发语言·数据库·php
ClouGence2 小时前
加一张临时表,OceanBase Oracle 写入居然快了 30 倍!
数据库·sql·oracle
tju23332 小时前
信创产业二十年:国产基础软件走到哪一步了?
数据库·gitee
东方护航数据恢复(深圳)3 小时前
RAID5单盘故障后阵列状态分析与重建风险评估_东方护航数据恢复深圳店
大数据·数据库
Richard.Wong3 小时前
Wispr Flow Notetaker 高效语音笔记实战指南
笔记