阶段四:MySQL8数据查询操作

数据查询语言(核心)

0、数据集准备

CREATE TABLE tb_product
(
    pid         INT PRIMARY KEY auto_increment,    -- p==product,pid==产品id编号
    pname       VARCHAR(20),                       -- 产品名称
    price       DOUBLE,                            -- 产品价格
    category_id VARCHAR(32)                        -- 产品所属分类编号(c001电子产品,c002服装)
) DEFAULT CHARSET=utf8mb4;

插入数据:

INSERT INTO tb_product VALUES (1,'联想',5000,'c001');
INSERT INTO tb_product VALUES (2,'海尔',3000,'c001');
INSERT INTO tb_product VALUES (3,'雷神',5000,'c001');
INSERT INTO tb_product VALUES (4,'杰克琼斯',800,'c002');
INSERT INTO tb_product VALUES (5,'真维斯',200,'c002');
INSERT INTO tb_product VALUES (6,'花花公子',440,'c002');
INSERT INTO tb_product VALUES (7,'劲霸',2000,'c002');
INSERT INTO tb_product VALUES (8,'香奈儿',800,'c003');
INSERT INTO tb_product VALUES (9,'相宜本草',200,'c003');
INSERT INTO tb_product VALUES (10,'面霸',10,'c003');
INSERT INTO tb_product VALUES (11,'好想你枣',5,'c004');
INSERT INTO tb_product VALUES (12,'香飘飘奶茶',10,'c005');
INSERT INTO tb_product VALUES (13,'海澜之家',200,'c002');
DataGrip软件关键字替换,可以使用Ctrl + R快捷键

1、select查询(核心)

# 根据某些条件从某个表中查询指定字段的内容
格式:select [distinct]*| 列名,列名 from 表 [where 条件]

select 查询哪些列多个列用逗号隔开 from 数据表 where 查询条件(满足条件的就显示,不满足的就忽略)

2、简单查询

-- 1.查询所有的商品.  
select * from tb_product;

-- 2.查询商品名和商品价格. 
select pname, price from tb_product;

-- 3.查询结果是表达式(运算查询):将所有商品的价格+10元进行显示.
select pname, price+10 from tb_product;

-- 4.查询所有商品对应的商品分类信息(不能重复)
select distinct category_id from tb_product;

3、五子句

SQL除了简单查询以外,还支持五子句查询(SQL查询五子句)

select */字段 from 数据表 ① where子句 ② group by子句 ③ having子句 ④ order by子句 ⑤ limit子句

① where:条件查询
② group by:分组查询
③ having:条件查询,只不过发生在分组之后,可以对分组后结果进行筛选
④ order by:排序子句,用于排序操作
⑤ limit:限制查询,用于限制查询数量
五子句可以单独出现,也可以多个关键词一起出现。但是不管多少个关键字都必须严格按照五子句顺序进行书写,否则报错!!!

4、条件查询(where子句)

作用:五子句的一部分

select \* from 数据表 where子句 group by分组子句 having子句 order by子句 limit子句

image

☆ 比较查询

-- 查询商品名称为“花花公子”的商品所有信息:
SELECT * FROM tb_product WHERE pname = '花花公子';

-- 查询价格为800商品
SELECT * FROM tb_product WHERE price = 800;

-- 查询价格不是800的所有商品
SELECT * FROM tb_product WHERE price != 800;
SELECT * FROM tb_product WHERE price <> 800;

-- 查询商品价格大于60元的所有商品信息
SELECT * FROM tb_product WHERE price > 60;

-- 查询商品价格小于等于800元的所有商品信息
SELECT * FROM tb_product WHERE price <= 800;

SELECT * FROM tb_product WHERE price > 60 并且 price <= 800

☆ 逻辑查询

逻辑上的与、或、非。其中,AND 与、OR 或、NOT 非。

-- 查询商品价格在200到1000之间所有商品
SELECT * FROM tb_product WHERE price >= 200 AND price <=1000;

-- 查询商品价格是200或800的所有商品
SELECT * FROM tb_product WHERE price = 200 OR price = 800 OR price = 1000;

-- 查询价格不是800的所有商品
SELECT * FROM tb_product WHERE NOT(price = 800);

☆ 范围查询

语法:

范围查询:between 低 and 高,表示区间查询;

精确匹配:in (A, B, C) 表示=A、或=B、或=C的数据

-- 查询商品价格在200到1000之间所有商品
SELECT * FROM tb_product WHERE price BETWEEN 200 AND 1000;

-- 查询商品价格是200或800或1000的所有商品
SELECT * FROM tb_product WHERE price IN (200, 800, 1000);
可以测试一下,BETWEEN 1000 AND 200,看看会是什么结果?

☆ 模糊查询

字段 like '匹配条件'

匹配条件有两个符号:%任意多个任意字符,\_只匹配任意某1个字符

-- 查询以'香'开头的所有商品
SELECT * FROM tb_product WHERE pname LIKE '香%';

-- 查询第二个字为'想'的所有商品
SELECT * FROM tb_product WHERE pname LIKE '_想%';    好想、好想你、好想你枣

☆ 空值查询 与 非空查询

where 字段=null(错误)

where 字段 is null(正确)

-- 查询没有分类的商品
select * from tb_product where category_id is null;

-- 查询有分类的商品
select * from tb_product where category_id is not null;

5、简单查询的常见用法(扩展)

☆ case when

简单查询中,还可以使用 case when 子句,进行字段的替换,通常用来替换字典或离职员工名字。


-- 比如,把gender的'0', '1'转换成男女
create table tb_employee (
    id int,
    name varchar(32),
    gender tinyint    -- 男0,女1
);

insert into tb_employee
    values (1, '张三', 0)
         , (2, '晓红', 1)
         , (3, '李四', 0)
;

select
    name,
    case gender when 0 then '男' else '女' end as '性别'
    from tb_employee;
应用场景
- 数据分类(如将数字转为文字描述)。
- 动态计算(如根据条件调整价格)。
- 行转列(如统计不同类型的数量)
【课下作业】
有一张表格,如下,
    序号      姓名    学科    成绩
    1        张三     语文    95
    2        张三     数学    98
    3        张三     英语    78
    4        李明     语文    98
    5        李明     数学    94
    6        李明     英语    85
    7        王冰     语文    86
    8        王冰     数学    89
    9        王冰     英语    85    

请转换成如下格式,输出展示
    姓名    语文    数学    英语
    张三    95        98    78
    李明    98        94    85
    王冰    86        89    85

提示:
    使用case when [else] end 语法进行处理;
    部分内容涉及到下一章的知识点——聚合函数,可以搜索AI

☆ left() 和 right()

LEFT(string, length):从字符串左侧开始,截取指定长度的字符

SELECT LEFT('HelloWorld', 5);  -- 输出 "Hello"

RIGHT(string, length):从字符串右侧开始,截取指定长度的字符

SELECT LEFT('HelloWorld', 5);  -- 输出 "World"
应用场景
- 提取固定长度前缀(如身份证前 6 位表示地区)。
- 截断超长字符串(如显示文章摘要)。
- 分隔路径(如 LEFT(file_path, LOCATE('/', file_path)-1))

☆ concat()

CONCAT() 是用于字符串拼接的核心函数,支持将多个字符串连接为一个。

SELECT CONCAT('a', 'b', 'c', 'd');  -- 输出 "abcd"

-- 若任一参数为 NULL,则结果为 NULL
SELECT CONCAT('Hello', NULL, 'World');  -- 输出 NULL

☆ 汇总

本节内容

<sheet sheet-id="QkbQQF" token="KWsrssTeqh2geutpuRIcNv0VnXd"></sheet>

其他常用函数

<sheet sheet-id="tp61JY" token="KWsrssTeqh2geutpuRIcNv0VnXd"></sheet>

DQL数据查询(进阶)

0、聚合函数

前置知识点:as关键词,用于给 数据表 或 数据表中的字段 定义别名

-- 数据表定义别名
select 
    别名.A,
    别名.B,
    ...
from 
    数据表 [as] 别名;
-- 比如
select
    tb_record.id,
    tb_record.name,
    tb_record.age
from
    db_itheima.tb_itheima_aiops_employee_record_log as tb_record;

-- 字段定义别名
select name, (chinese+english+math) [as] 别名 from 数据表;    -- 这里得到语数外三科的总分
-- 比如
select name as '姓名',  (chinese+english+math) as '总分' from tb_score;
as 可加可不加,通常都会加上,增强可读性

作用:

之前我们做的查询都是横向查询,它们都是根据条件一行一行的进行判断。

而使用聚合函数查询是纵向查询,它是对一列的值进行计算,然后返回一个单一的值;

另外聚合函数会忽略空值。

聚合查询:

① 纵向查询(按列查询)

② 默认会忽略空值

今天我们学习如下五个聚合函数:

聚合函数作用
count()统计指定列不为NULL的记录行数;
sum()计算指定列的数值和,如果指定列类型不是数值类型,则计算结果为0
max()计算指定列的最大值,如果指定列是字符串类型,使用字符串排序运算;
min()计算指定列的最小值,如果指定列是字符串类型,使用字符串排序运算;
avg()计算指定列的平均值,如果指定列类型不是数值类型,则计算结果为0

实现原理:

image

案例演示:

drop table if exists tb_score;

create table tb_score(
    name    varchar(32),
    math    int
);

insert into tb_score
    values ('张三', 90),
           ('小明', 80),
           ('李四', 85),
           ('李辉', null);

-- 聚合函数
select count(math) from tb_score;

1、分组查询(group by 子句)

作用:分组就是为了更好的进行数据的统计,分组 + 聚合。

按性别分组、按学科分组、按部门分组、按年级分组 => group by 分组字段A, 分组字段B(按这个字段进行划分分组)

光有分组一般没有特别的意义,但是有一个特性:去重(因为分组完,只展示一个,后面会演示)
面试过程中:
介绍一下,在SQL语句中,如何实现去重操作?
答:
我了解的一共有两种方式,distinct 或 group by

☆ 基本概念

分组查询就是将查询结果按照指定字段进行分组,字段中数据相等的分为一组。

分组查询基本的语法格式如下:GROUP BY 列名 [HAVING 条件表达式]

说明:

☆ group by

group by可用于单个字段分组,也可用于多个字段分组

-- 准备学生表students
create table students(
    id     int   auto_increment,    -- auto_increment 表示自增
    name   varchar(20),
    age    tinyint unsigned,        -- 无符号小整型(或无符号微整型)
    gender enum('male', 'female'),
    score  tinyint,
    primary key(id)        -- 这里单独一行声明主键,也是可以的
) default charset=utf8mb4;
show tables;

insert into students values (null, 'Tom', 23, 'male', 97);    -- 会自动添加 id的
insert into students values (null, 'Jack', 24, 'male', 88);
insert into students values (null, 'Rose', 26, 'female', 99);
insert into students values (null, 'Eric', 27, 'male', 59);
insert into students values (null, 'Jennifer', 22, 'female', 76);

select * from students;

-- 根据gender字段来分组
select gender from students group by gender;     -- 会发现输出结果去重了
-- 根据name和gender字段进行分组
select name, gender from students group by name, gender;    -- 会发现输出结果去重了

① group by可以实现去重操作

② group by的作用是为了实现分组统计(group by + 聚合函数)

☆ group by + 聚合函数的使用

-- 统计不同性别的人的平均年龄
select gender, avg(age) from students group by gender;

-- 统计不同性别的人的个数
select gender, count(*) from students group by gender;

-- 字符串聚合,了解即可
select category_id, group_concat(pname) from tb_product group by category_id;
image

group by使用注意事项:

select 分组字段, 聚合函数, 聚合函数 from students group by 分组字段;

SQL官方文档:在有group by出现的情况下,select后面的字段要么只能出现在分组中,要么只能出现在聚合函数中

2、过滤(having 子句)

having作用和where类似都是过滤数据的,但是两者之间的执行顺序不同

① where子句(发生在分组之前)

② group by子句 (分组)

③ having子句(发生在分组之后)

☆ 第一种情况:如果只是简单的查询操作(没有group by的情况),大部分时间having是可以直接替代where子句

select * from tb_product where price > 800;

以上语句等价于

select * from tb_product having price > 800;
image

☆ 第二种情况:

-- 根据gender字段进行分组,统计分组条数大于 2 的
select gender, count(*) from students group by gender having count(*) > 2;

案例演示:

-- 1 统计各个分类商品的个数
select category_id, count(*) from tb_product group by category_id;

-- 2 统计各个分类商品的个数,且只显示个数大于 1 的信息
select category_id, count(*) from tb_product group by category_id having count(*) > 1;

3、排序查询(order by 子句)

-- 通过order by语句,可以将查询出的结果进行排序。暂时放置在select语句的最后。
-- 格式:SELECT * FROM 表名 ORDER BY 排序字段 ASC|DESC;
ASC(Ascend /əˈsend/)      升序 (默认),默认情况下,ASC关键词可以省略不写
DESC (Descend /dɪˈsend/)    降序

-- 1.使用价格排序(降序)
select * from tb_product order by price desc;

-- 2.在价格排序(降序)的基础上,以品类排序(降序)
select * from tb_product order by price desc, category_id desc;
-- 首先按照第一个字段排序,如果第一个字段能比较出大小,则不需要进行字段2排序;
-- 如果第一个字段值相同,则系统会继续按照第二个字段进行排序

4、分页(limit子句)

应用场景:① 限制查询 ② 分页查询

限制查询:主要限制数据查询的数量(获取数据表中的前3条数据)

select * from 数据表 limit 查询数量;

select * from 数据表 limit 偏移量(默认为0,类似索引下标),查询数量;

偏移量:索引下标,默认从0开始

0 第一条记录

1 第二条记录

2 第三条记录

-- 基本语法1:select * from 数据表 limit 查询数量;
-- 案例1:查询学生表中,成绩最高的学生信息(只查1个)
select * from students order by score desc limit 0, 1;    -- 从0开始,只查一个
-- 等价于
select * from students order by score desc limit 1;      -- 只查一个
-- 缺点说明:如果一个学生表有多个同学成绩相同,可能会导致,只能查出1名同学。

-- 基本语法2:select * from 数据表 limit 偏移量(从哪查默认为0,类似索引下标),查询数量;
-- 案例2:查询学生表中,成绩第2高(第2名)的学生信息
select * from students order by score desc limit 1, 1;   -- 因为下标从 0 计算,所以这里 1 表示第二个

分页查询:实际特别接近,因为只要有分页的地方,底层100%都是使用limit子句实现的

image

分页查询在项目开发中常见,由于数据量很大,显示屏长度有限,因此对数据需要采取分页显示方式。例如数据共有30条,每页显示5条,第一页显示1-5条,第二页显示6-10条。

image

格式:

SELECT 字段1,字段2... FROM 表名 LIMIT M,N
    M: 整数,表示从第几条索引开始,计算方式 (当前页-1)* 每页显示条数
    N: 整数,表示查询多少条数据
SELECT 字段1,字段2... FROM 表明 LIMIT 0,5
SELECT 字段1,字段2... FROM 表明 LIMIT 5,5

总结

SQL查询五子句分别为:(where子句)、(group by子句)、(having子句)、(order by子句)、(limit子句)

----------------------------------------------------------------------
条件查询:select *|字段名 form 表名 where 条件;

聚合查询函数:count(),sum(),max(),min(),avg(),了解 group_concat()。
分组查询:SELECT 字段1,字段2… FROM 表名 GROUP BY 分组字段 HAVING 分组条件;

排序查询:SELECT * FROM 表名 ORDER BY 排序字段 ASC|DESC;
分页查询:
SELECT 字段1,字段2... FROM 表名 LIMIT M,N
M: 整数,表示从第几条索引开始,计算方式 (当前页-1)*每页显示条数
N: 整数,表示查询多少条数据

多表查询(重点)

0、表与表之间的关系

在SQL语句中,数据表与数据表之间,如果存在关系,一般一共有3种情况:

① 1:1,一对一关系(高级)

比如有A、B两张表,A表中的每一条数据,在B表中有一条唯一的数据与之对应。

用户表 tb_user

user_id(用户编号)账号username密码password
001adminadmin888
002itheima123456

用户详情表 tb_user_items

user_id(用户编号)真实姓名年龄联系方式
001张三1610086
002李四1810010
其中,user_id是一一对应的

我们把用户表与用户详情表之间的关系就称之为一对一关系。

② 1:N,一对多关系(重点)

比如有A、B两张表,A表中的每一条数据,在B表中都有多条数据与之对应,我们把这种关系就称之为一对多关系

产品分类表

分类id编号分类名称
1手机
2电脑

产品信息表

产品id编号产品名称产品价格所属分类id编号
1Apple iPhone 136799.001
2Redmi Note 93499.001

我们把产品分类表与产品表之间的(分类id的对应)关系就称之为一对多关系。

③ M:N,多对多关系(高级)

用户表

用户编号登录账号登录密码
1adminadmin888
2itheima123456

权限表

权限id编号权限名称
1增加
2删除
3修改
4查询

虽然从以上图解来看,两者之间好像没有任何联系,但是两者之间其实是有关系的。

这种关系需要通过一张临时表进行呈现。

每个用户,应该有对应的权限,admin账号可以做增删改查,itheima账号可以做查询

反过来

每个权限都应该对应多个用户,查询权限 => admin/itheima

注意:如果两张表之间的关联关系为多对多关系,则必须建立一个中间表,在中间表中体现两者的关系。

中间表 :用户_权限表

image

1、交叉连接(笛卡尔积)

准备数据集:

-- 1. 准备数据集
-- 数据表classes,拥有两个字段,cls_id代表班级编号,cls_name代表班级名称
use db_itheima;
drop table classes;
create table classes(
    cls_id int,
    cls_name varchar(20)
) default charset=utf8mb4;

-- 插入数据,ui、java、python
insert into classes values
    (1, 'UI'),
    (2, 'Java'),
    (3, 'Python');

-- 数据表students,拥有id、name、age、gender值使用male和female、score、cls_id
drop table students;
create table students(
    id int,
    name varchar(20),
    age int,
    gender enum('male', 'female'),
    score decimal(11,2),
    cls_id int
) default charset=utf8mb4;

-- 插入数据,刘备属于Java,貂蝉属于UI,赵云属于Python,关羽属于Python,大乔属于UI
insert into students values
    (1, '刘备', 18, 'male', 100.00, 2),
    (2, '貂蝉', 18, 'female', 99.00, 1),
    (3, '赵云', 18, 'male', 98.00, 3),
    (4, '关羽', 18, 'male', 96.00, 3),
    (5, '大乔', 18, 'female', 97.00, 1);

-- 交叉连接也称之为笛卡尔积连接  
select * from students cross join classes;
-- 或
select * from students, classes;
image

没有意义,但是它是所有连接的基础。其功能就是将表1和表2中的每一条数据进行连接。

结果:

字段数 = 表1字段 + 表2的字段

记录数 = 表1中的总数量 \* 表2中的总数量(笛卡尔积)

select * from classes;    -- 单独查看
select * from students;   -- 单独查看
image

☆ 关于笛卡尔

笛卡尔 —— 我思故我在

image
笛卡尔在解析几何的贡献
相传,有一天,笛卡尔生病卧床,病情很重,尽管如此他还反复思考一个问题:几何图形是直观的,而代数方程是比较抽象的,能不能把几何图形和代数方程结合起来,也就是说能不能用几何图形来表示方程呢?
突然,他看见屋顶角上的一只蜘蛛,拉着丝垂了下来。一会功夫,蜘蛛又顺这丝爬上去,在上边左右拉丝。蜘蛛的“表演”使笛卡尔的思路豁然开朗。他想,可以把蜘蛛看作一个点。他在屋子里可以上,下,左,右运动。
如果把地面上的墙角作为起点,把交出来的三条线作为三根数轴,那么空间中任意一点的位置就可以在这三根数轴上找到有顺序的三个数。
由此引出了直角坐标系的概念。因此,直角坐标系,又称为笛卡尔坐标系。

2、连接查询的介绍

连接查询可以实现多个表的查询,当查询的字段数据来自不同的表就可以使用连接查询来完成。

连接查询可以分为:

1. 内连接查询(也是默认连接) 2. 左外连接查询 3. 右外连接查询 4. 自连接查询(自己查询自己)

☆ 内连接(inner join)

查询两个表中符合条件的共有记录

image

内连接查询语法格式: inner join ... on 关联条件

select 字段 from 表1 inner join 表2 on 表1.字段1 = 表2.字段2;

-- 进行适当缩进和换行
select
    字段
from
    表1
    inner join 表2 on 表1.字段1 = 表2.字段2;

说明:

例1:使用内连接查询学生表与班级表,查询每个学生对应的具体班级信息。

-- 案例:求每个学生所属的班级信息(学生所有字段 + 班级名称)
select *
from
    students
    inner join classes
               on students.cls_id = classes.cls_id;

-- 内连接基础上可以筛选想要的字段
select
    students.*
  , classes.cls_name
from
    students
    inner join classes
               on students.cls_id = classes.cls_id;

-- 引入表别名机制,数据表名称 [as] 别名
select 
    s.name
    , s.age
    , s.gender
    , c.cls_name 
from students s 
inner join classes c 
        on s.cls_id = c.cls_id;

-- 通过 换行+缩进 提升可读性,inner join on 还可以简写为 join on
select
    s.name
  , s.age
  , s.gender
  , c.cls_name
from
    students as s
    join classes as c -- join 默认就是 inner join
         on s.cls_id = c.cls_id;

小结

☆ 左外连接(left join)

有一个主表概念,默认情况下,关联后会保留主表的所有记录。

以左表为主根据条件查询右表数据,如果根据条件查询右表数据不存在,使用null值填充

商品分类表

编号分类名称
1手机
2电脑

商品表

编号商品名称商品分类编号
1Vivo手机1
2Xiaomi手机1

左外连接查询:select \* from 分类表(主表) left join 商品表 on 分类表.编号 = 商品表.分类编号;

编号分类名称编号商品名称商品分类编号
1手机1Vivo手机1
1手机2Xiaomi手机1
2电脑nullnullnull

左外连接默认会保留左表,然后与右边的表进行匹配;如果匹配到,则显示右表对应的数据;匹配不到,也要显示。只不过右表的所有字段使用null进行填充!

image

左连接查询语法格式:

select
    字段
from
    表1
    left join 表2
              on 表1.字段1 = 表2.字段2

说明:

例1:使用左连接查询学生表与班级表,获取每一学生对应的班级信息,要求没有对应的班级也要显示。

-- 使用左连接查询学生表与班级表,获取每一学生对应的班级信息,要求没有对应的班级也要显示。
insert into students values (6, '曹操', 30, 'male', 98, 9);

-- 左连接
select
    s.*
  , c.cls_name
from
    students s
    left join classes c on s.cls_id = c.cls_id;
image

小结

☆ 右外连接(right join)

以右表为主根据条件查询左表数据,如果根据条件查询左表数据不存在则使用null值填充

image

右连接查询语法格式:

select
    字段
from
    表1
    right join 表2(主表) on 表1.字段1 = 表2.字段2        -- 右连接

select *
from 表2
    left join 表1

说明:

例1:使用右连接查询学生表与班级表:

-- 查看班级中对应的学生信息,如果某个班级没有对应的学生也要显示。(既可以用左外连接也可以用右外连接)
select
    s.*
  , c.cls_name
from
    students s
    right join classes c on s.cls_id = c.cls_id;

select
    s.*
  , c.cls_name
from
    classes c
    right join students s on c.cls_id = s.cls_id;
image
image

小结

☆ 自连接查询(了解)

自连接查询:数据表自己连接自己,本质只有1张数据表,表内部数据有层级关系,比如,地区字典表。

前提:连接操作时必须为数据表定义别名!

左表和右表是同一个表,根据连接查询条件查询两个表中的数据。

两个实际的工作场景:求省市区信息,求分类导航信息

① 省份表 + 城市表 + 区域表(理论,实际设计表的过程中,通常只有1张数据表)

② 大类 + 中类 + 小类(理论,实际设计表的过程中,通常只有1张数据表)

地域:title

pid 全称 parent id(父级ID编号),如果pid值为null代表本身就是父级,如果pid是一个具体的数值,则代表其属于子级

image

例1:查询省的名称为“广东省”的所有城市

创建areas表:

use db_itheima;
create table areas (
    aid    int not null AUTO_INCREMENT,
    atitle varchar(20),
    pid    int,
    primary key (aid)
);

执行sql文件给areas表导入数据:

insert into areas
values (1, '广东省', null),
       (2, '山西省', null),
       (3, '深圳市', 1   ),
       (4, '广州市', 1   ),
       (5, '太原市', 2   ),
       (6, '大同市', 2   ),
       (7, '河南省', null),
       (8, '郑州市',7),
       (9, '洛阳市', 7);
image

自连接查询的用法:

-- 第一步:把两张表关联查询(内连接)
select *
from
    areas p
    inner join areas c on p.aid = c.pid;
image
-- 第二步:在以上查询基础上,获取省份名称为广东省
select *
from
    areas p
    inner join areas c on p.aid = c.pid
where p.atitle = '广东省';
image
-- 第三步:只显示城市信息
select
    c.atitle
from
    areas p
    inner join areas c on p.aid = c.pid
where p.atitle = '广东省';

说明:

小结

总结

<sheet sheet-id="Wf5vyB" token="KWsrssTeqh2geutpuRIcNv0VnXd"></sheet>

3、子查询(扩展)

☆ 子查询(嵌套查询)的介绍

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

外部那个select语句则称为主查询语句。

select \* from (select \* from xxx) as t;

作用:子查询比较适合复杂查询以及多层级查询结构。

主查询和子查询的关系:

1. 子查询是嵌入到主查询中 2. 子查询是辅助主查询的,要么充当条件,要么充当数据源(数据表) => 要么出现在where,要么出现在from位置 3. 子查询是可以独立存在的语句,是一条完整的 select 语句

了解:子查询的应用场景

答:在我们需求的基础上,如果这个需求需要通过多条SQL语句分步查询的情况,一般都需要基于子查询。

注:子查询会全表扫描两次,大数据量下需谨慎使用。所以我们说了解就行。

总结

子查询是一个完整的SQL语句,子查询被嵌入到一对小括号里面,子查询可以充当条件,也可以充当数据表使用。

掌握子查询编写三步走:

① 编写子查询

② 编写主查询并融合伪代码

③ 伪代码替换为子查询

子查询会全表扫描两次,大数据量下需谨慎使用。