软件测试-MySQL语言基础-2多表查询

连接查询

1.基本概念

  • 当查询结果来源多张表时,需要将多张表连接成一个大的数据集,再选择合适的结果返回。
  • 连接查询可以通过连接运算符(连接条件)可以实现多个表查询。
  • 内连接:查询的结果只显示两个表中满足连接条件的部分。
  • 20250501140527325-image

    左连接:查询的结果为两个表匹配得到的数据,加左表特有的数据,对于右表中不存在的数据使用null填充。

  • 20250501140647350-image

    右连接:查询的结果为两个匹配得到的数据,加右表特有的数据,对于左表中不存在的数据使用null填充。

  • 20250501140810521-image

2.内连接 inner join

2.1 标准语法

select * from 表1 inner join 表2 on 表1+匹配字段名 = 表2+匹配字段名;

  • 创建表a和表b,并向其插入数据。
  • -- 如果表a存在则删除,不存在则不做任何操作
    drop table if exists a;
    
    -- 创建表a
    create table a (
      id int,
      name varchar(10)
    );
    
    -- 向表a中插入数据
    insert into a values(1,'张三'),(2,'李四'),(3,'王五');
    
    select * from a;
    
    -- 如果表b存在则删除,不存在则不做任何操作
    drop table if exists b;
    
    -- 创建表b
    create table b(
     id int,
     score int
    );
    
    -- 向表b中插入数据
    insert into b values(1,30),(1,40),(2,50),(2,60);
  • 表a和表b数据展示。
  • 20250501150837915-image

    表a和表b通过字段id内连接查询后的结果。

    • select * from a inner join b on a.id = b.id;
    • 20250501151521648-image

  • 查询结果列的说明:
    • 表a和表b的列都会出现在查询结果中,由于表a和表b都有列名叫id 的字段,为了区分,表b 的id列显示为id1.
  • 查询结果行的说明:
    • 记录只保留表a 和表 b 中id字段相同的记录。
students表和scores表的数据说明

20250501151854232-image

查询学生信息和学生的成绩,只显示有成绩的学生。

  • select * from students inner join scores on students.studentNo = scores.studentNo;
  • 查询结果只显示students 和scores两个表中studentNo相同的部分。
  • 20250501152415405-image

2.2隐式链接

select * from 表1,表2 where 表1.字段 = 表2.字段;

查询学生的信息和成绩,只显示有成绩的学生。

  • select * from students,scores where students.studentNo = scores.studentNo;
  • 20250501154114266-image

2.3选择部分字段

查询学生信息,要求只显示姓名、课程、成绩。

  • 标准语法:
    • select name,courseNo,score from students inner join scores on students.studentNo = scores.studentNo;
  • 隐式链接:
    • select name,courseNo,score frmo where students.studentNo = scores.studentNo;
  • 20250501155452587-image

2.4表的别名

查询学生信息,要求只显示姓名、课程号、成绩,其中表students别名stu,表scores别名sc。

  • select name,courseNo,score from students as stu inner join scores as sc on stu.studentNo = sc.studentNo;
  • 20250501160018311-image

— 练习

查询成绩表信息,同时显示成绩对应的课程表。

  • select * from students inner join scores,courses on students.studentNo = scores,studentNo and scores.courseNo = courese.course.NO;

2.5带有wuere条件的内连接

  • 语法格式
    • select * from 表1 inner join 表2 on 表1.字段 = 表2.字段 where 条件;

查询王昭君的信息,要求只显示姓名,课程号,成绩。

  • select name,courseNo,score from students inner join scores on students.studentNo = scores.studentNo where students.name = ‘王昭君’;
  • 20250501165917451-image

2.6带有and逻辑运算符的内连接查询

查询姓名为王昭君 并且成绩小于90的信息,要求只显示姓名,成绩。

  • select name 姓名,score 成绩 from students
    inner join scores on students.studentNo = scores.studentNo
    where students.name = ‘王昭君’ and scores.score < 90;
  • 20250501170425797-image

2.7多表内连接查询

查询学生信息和成绩以及成绩对应的课程名称。

  • select * from students
    inner join scores on students.studentNo = scores.studentNo
    inner join courses on scores.courseNo = courses.courseNo;
  • 20250501170806239-image

— 练习

写sql三步法:

  • 搭建框架
    • 基本的select语句框架搭建起来,如果有多表,把相应的多表也联合起来。
  • 看条件
    • 决定where后面的具体条件。
  • 显示的字段
    • select 后面到底要显示什么字段。

查询所有学生的Linux课程成绩,要求只显示姓名,成绩,课程名称。

  • select name,score,coursename from students
    inner join scores on students.studentNo = scores.studentNo
    inner join courses on scores.courseNo = courses.courseNo
    where courses.coursename = ‘Linux’;
  • 20250501172701909-image

2.8带有order by 排序的内连接查询

查询成绩最高的男生信息,要求只显示姓名,课程名,成绩。

  • select name , coursename ,score from students
    inner join scores on students.studentNo = scores.studentNo
    inner join courses on scores.courseNo = courses.courseNo
    where students.sex = ‘男’
    order by scores.score desc
    limit 1;
  • 20250501172417128-image

3.左连接 left join

  • 语法格式
    • select * from 表1
      left join 表2 on 表1.字段 = 表2.字段;

20250501172913591-image

查询所有学生的信息以及成绩,包括没有成绩的学生。

  • students 表中有些学生在scores表中没有成绩;
  • 左连接查询的结果为students和scores两个表匹配得到的数据,加上students表特有的数据,对于students表中不存在的数据使用null填充。

4.右连接 right join

  • 语法格式
    • select * from 表1
      right join 表2 on 表1.字段 = 表1.字段;
  • 20250501175138219-image

查询所有课程的信息,包括没有成绩课程。

  • courses表中courseNo为7的课程 python 在scores 表中没有对应的成绩;
  • 右连接查询的结果为 scores 和courses 两个表匹配得到的数据,加courses表特有的数据,对于scores表中不存在的数据使用null填充。
    • select * from scores right join courses on scores.courseNo = courses.couseNo;
  • 20250501175620372-image

注意事项

多表联合查询,重名字段的处理方式:

  • 如果一条select 要用到多个表,且表中有同名字段,就需要表名.字段名 加以区分。

自关联

1.背景思考

  • 设计省信息的表结构 provinces;
    • proid:省略号;
    • pname:省结构;
  • 升级市信息的表结构 citys。
    • cityid:市编号;
    • cname:市名称;
    • proid:市所属的省编号;
  • citys表的 proid表示城市所属的省,对应着provinces表的proid值。

问题:

能不能将两个表合成一张表呢?

思考:

观察两张表发现,citys表 比 province表 多一个字段 proid,其它字段的类型都是一样的。

意义:

存储的都是地区信息,而且每种信息的数量有限,没必要增加一个新表,或者将来还要存储区,乡镇信息,都增加新表的开销太大。

答案:

定义表areas,结构如下:

  • id
  • name
  • pid

表中的一条记录,可以记录省,也可以记录市。

  • 记录为省的时候,字段说明:
    • id:代表省
    • name:代表省名称
    • pid:因为省没有所属的省份,所以pid写为null。
  • 记录为市的时候,字段说明:
    • id:代表市id
    • name:代表市名称
    • pid:代表市所属省id

这就是自关联,表中的某一字段,关联了这个表中的另外一字段,但是它们的业务逻辑含义是不一样的,城市信息的pid引用的是省信息的id。

在这个表中,结构不变,以后还可以扩充区县,乡镇街道,村社区等信息。

1. 创建区域表areas,向表中插入数据

20250501201443316-image

查询一共有多少个省。

  • select count(*) from areas where pid is null;
  • 20250501202454560-image

查询广东省的所有城市

  • select * from areas p inner
    join areas c on p.id = c.pid
    where p.name = ‘广东省’;
  • 20250501210329264-image

  • 子关联是同一张表作为连接查询。
  • 子关联下,一定找到同一张表可关联的不同字段。

子查询

1.定义

  • 在一个select 语句中,嵌入了另外一个select语句,那么被嵌入的select语句称之为子查询语句。

主查询

  • 外层的第一条select语句为主查询。

主查询和子查询的关系

  • 子查询是嵌入到主查询中。
  • 子查询是辅助主查询的,要么充当条件,要么充当数据资源。
  • 子查询是可以独立存在的语句,是一条完整的select 语句。
  • 主查询离开子查询是不能独立运行的,依赖子查询的结果。

查询大于平均年龄的学生记录。

格式一

使用两条select语句实现。

  • 第一步:查询平均年龄
    • select avg(age) from students;
    • 20250501203044499-image

  • 根据第一步的结果,查询大于平均年龄的学生记录。
    • select * from students where age>30.1667;
    • 20250501203352102-image

格式二

用子查询实现。

  • select * from students where age > (select avg(age) from students);
  • 20250501203534968-image

标量子查询:例如1格式中,子查询返回的结果只有一个值(一行一列),这种称为标量子查询。

查询30岁的学生的成绩

格式一:

使用两条select 语句实现。

  • 查询30岁学生的学号
    • select studentNo from students where age = 30;
  • 根据学号查询成绩。
    • select score from scores where studentNo in (‘001′,’003′,’011’);
  • 20250501204459404-image

格式二:

使用子查询实现。

  • select score from scores where studentNo in (select studentNo from students where age = 30);
  • 20250501205555774-image

列子查询:比如例2格式二中,子查询返回的结果是一列(一列多行),这种称之为列子查询。

用子查询,查询所有女生的信息和成绩。

  • select * from (select * from students where sex=’女’) as  stu
    inner join scores as sc
    on stu.studentNo = sc.studentNo;
  • 20250501205934718-image

表级子查询:比如例3中,子查询返回的结果是多行多列(一个表),这种称之为表级子查询。

THE END
喜欢就支持一下吧
赞赏 分享