SQL 联合查询

📅 2026/7/18 5:29:24
SQL 联合查询
联合查询也叫多表查询使用的前提条件, 联合查询的表,需要有一定的关系(一对一, 一对多, 多对多......). 没有关系的话. 联合查询的结果, 无异议~~1. 为什么要使⽤联合查询在数据设计时由于范式的要求数据被拆分到多个表中那么要查询⼀个条数据的完整信息就要从多个表中获取数据2. 笛卡尔积数学上的概念. 就是一个 排列组合 笛卡尔积是两个表中的运算,通过排列组合的方式, 形成一张 大表 create table class(class_id int, class_name varchar(20)); insert into class values(1,java100),(2,java101); create table student(id int, name varchar(20),class_id int); insert into student values(100,张三,1),(101,李四,1),(102,王五,2),(103,赵六,2); select * from student; select * from class; select * from student, class;笛卡尔积 排列组合, 把所有的情况, 都罗列出来了 .其实这里包含了无效数据那些是合理的数据, 有啥特点?链接条件, 两个表进行笛卡尔积的时候,其中对应列的值,相同, 此时数据就应该被筛选出来, 作为合理的数据select * from student, class where student.class_id class.class_id;要进行 多表联合查询1.先进行笛卡尔积2.通过链接条件,进行筛选3.根据实际需求场景, 进一步添加其他条件 / order by / limit4.针对列进行筛选/计算 / 分组 / 聚合多表查询并不复杂,但是写的时候,有点麻烦~~构造练习案例数据# 课程表 insert into course (name) values (Java), (C), (MySQL), (操作系统), (计 算机⽹络), (数据结构); # 班级表 insert into class(name) values (Java001班), (C001班), (前端001班); # 学⽣表 insert into student (name, sno, age, gender, enroll_date, class_id) values (唐三藏, 100001, 18, 1, 1986-09-01, 1), (孙悟空, 100002, 18, 1, 1986-09-01, 1), (猪悟能, 100003, 18, 1, 1986-09-01, 1), (沙悟净, 100004, 18, 1, 1986-09-01, 1), (宋江, 200001, 18, 1, 2000-09-01, 2), (武松, 200002, 18, 1, 2000-09-01, 2), (李逹, 200003, 18, 1, 2000-09-01, 2), (不想毕业, 200004, 18, 1, 2000-09-01, 2); # 成绩表 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), (80, 7, 2),(92, 7, 6);3. 案例⼀个完整的联合查询的过程查询学⽣姓名为孙悟空的详细信息包括学⽣个⼈信息和班级信息1.首先确定这个操作要查询的数据,来自哪些表.2.确定是否存在可以关联的id 这俩实体是否有关系.1)笛卡尔积# 第一步计算笛卡尔积 select * from student,class;2) 链接条件# 2.引入链接条件 select * from student,class where student.class_id class.class_id;3) 添加更多的条件# 再次添加条件 select *from student, class where student.class_id class.class_id and student.name 孙悟空;4)针对列进行筛选/计算表达式/聚合查询# 针对列进行筛选 select student.name, student.age, student.gender, student.enroll_date, class.name from student, class where student.class_id class.class_id and student.name 孙悟空;4. 内连接join on(把 , 替换成join where替换成on)select student.name, student.age, student.gender, student.enroll_date, class.name from student join class on student.class_id class.class_id where student.name 孙悟空;5. 外连接外连接分为左外连接、右外连接.外连接返回左表的所有记录和右表中匹配的记录。如果右表中没有匹配的记录则结果集中对应字段会显⽰为NULL。右外连接与左外连接相反返回右表的所有记录和左表中匹配的记录。如果左表中没有匹配的记录则结果集中对应字段会显⽰为NULL。1.左外连接 left join2.右外连接 right joinuse java118_2; create database java118_2; show tables; create table student(id int,name varchar(20)); create table score(student_id int, score int); insert into student values(1,张三),(2,李四),(3,王五); insert into score values(1,90),(2,80),(3,70); select * from student; select * from score;在上述两个表中数据是一一对应的.对于这种一一对应 的情况, 内连接和外连接完全等价-- 左外连接表1完全显⽰ select 字段名 from 表名1 left join 表名2 on 连接条件; -- 右外连接表2完全显⽰ select 字段 from 表名1 right join 表名2 on 连接条件;6. 自连接同一个表 , 自己和自己连接通过自连接, 把行和行之间的关系,转成列和列之间的关系!!!!!!示例 :显⽰所有MySQL成绩⽐JAVA成绩⾼的成绩信息select * from score as s1,score as s2;不使用别名会报错!!!select * from score as s1,score as s2 where s1.student_id s2.student_id and s1.course_id 3 and s2.scorse 1 and s1.score s2.score;7.合并查询⽰例查询student表中 id 3 的同学和student1表中的所有同学select * from student where student_id 3 UNION select * from student1;union自动去重union all不去重确保合并的两组查询结果,列的个数/类型 要匹配