(重点)MySQL(入门篇11)单表子查询。

一、是什么?

1.定义

在一个表达式中调用另一个表达式,就叫子查询(subQuery),也称为子选择(subSelect),或者内嵌选择(inner select

2.本质

3. 4种分类

1.分类

分类 返回 使用
表子查询 返回 N行 N列 FROM语句中使用
行子查询 列的集合1行 N列(记做:行只有一行) 用于 From和 where
列子查询 返回行的集合N行1列 from 和 where
标量子查询 1行1列

注意:这个是n行n列是在 (where)语句里的n行n列,不是查询总结果的

2.4种子查询关系组成关系如图:

在这里插入图片描述

二、怎么用?

1. 三种子查询方法

关键字 解释 定义
where 把内层的结果,作为外层的比较条件
from 内层的结果提供给外层再次查询 把子查询的结果当做一张临时表,然后对他进行处理
exist 把外层的结果拿到内层看内层的查询是否成立 对外表进行循环,然后对内表进行查询,和 in()差不多,、但是使用不同(子查询大就用exist 内层索引,子查询小就用in 外层索引)

四、实例分析

1. 建表.

/*
一、建表
1.players为球员信息基本表,表penalties为有过罚款记录的球员信息列表。
2.PENALTIES 是罚款表 
*/
CREATE TABLE PLAYERS
    (PLAYERNO      INTEGER      NOT NULL,
    NAME           CHAR(15)     NOT NULL,-- 名称
    INITIALS       CHAR(3)      NOT NULL,-- 首字母
    BIRTH_DATE     DATE                 ,-- 出生时间
    SEX            CHAR(1)      NOT NULL,-- 性别
    JOINED         SMALLINT     NOT NULL,-- 出道时间
    STREET         VARCHAR(30)  NOT NULL, -- 街道
    HOUSENO        CHAR(4)              ,-- 房间号码
    POSTCODE       CHAR(6)              ,-- 邮编
    TOWN           VARCHAR(30)  NOT NULL,-- 城镇名称
    PHONENO        CHAR(13)             ,-- 电话
    LEAGUENO       CHAR(4)              ,-- 社团号码.
    PRIMARY KEY    (PLAYERNO));
 
CREATE   TABLE PENALTIES 
        (PAYMENTNO      INTEGER      NOT NULL,-- pay method付款方式
         PLAYERNO       INTEGER      NOT NULL,-- 球员号 -主键.
         PAYMENT_DATE   DATE         NOT NULL,-- 付款时间
         AMOUNT         DECIMAL(7,2) NOT NULL,-- 金额
         PRIMARY KEY    (PAYMENTNO));

2. 数据

INSERT INTO PLAYERS VALUES (2, 'Everett', 'R', '1948-09-01', 'M', 1975, 'Stoney Road','43', '3575NH', 'Stratford', '070-237893', '2411');
INSERT INTO PLAYERS VALUES (6, 'Parmenter', 'R', '1964-06-25', 'M', 1977, 'Haseltine Lane','80', '1234KK', 'Stratford', '070-476537', '8467');
INSERT INTO PLAYERS VALUES (7, 'Wise', 'GWS', '1963-05-11', 'M', 1981, 'Edgecombe Way','39', '9758VB', 'Stratford', '070-347689', NULL);
INSERT INTO PLAYERS VALUES (8, 'Newcastle', 'B', '1962-07-08', 'F', 1980, 'Station Road','4', '6584WO', 'Inglewood', '070-458458', '2983');
INSERT INTO PLAYERS VALUES (27, 'Collins', 'DD', '1964-12-28', 'F', 1983, 'Long Drive','804', '8457DK', 'Eltham', '079-234857', '2513');
INSERT INTO PLAYERS VALUES (28, 'Collins', 'C', '1963-06-22', 'F', 1983, 'Old Main Road','10', '1294QK', 'Midhurst', '010-659599', NULL);
INSERT INTO PLAYERS VALUES (39, 'Bishop', 'D', '1956-10-29', 'M', 1980, 'Eaton Square','78', '9629CD', 'Stratford', '070-393435', NULL);
INSERT INTO PLAYERS VALUES (44, 'Baker', 'E', '1963-01-09', 'M', 1980, 'Lewis Street','23', '4444LJ', 'Inglewood', '070-368753', '1124');
INSERT INTO PLAYERS VALUES (57, 'Brown', 'M', '1971-08-17', 'M', 1985, 'Edgecombe Way','16', '4377CB', 'Stratford', '070-473458', '6409');
INSERT INTO PLAYERS VALUES (83, 'Hope', 'PK', '1956-11-11', 'M', 1982, 'Magdalene Road','16A', '1812UP', 'Stratford', '070-353548', '1608');
INSERT INTO PLAYERS VALUES (95, 'Miller', 'P', '1963-05-14', 'M', 1972, 'High Street','33A', '5746OP', 'Douglas', '070-867564', NULL);
INSERT INTO PLAYERS VALUES (100, 'Parmenter', 'P', '1963-02-28', 'M', 1979, 'Haseltine Lane','80', '6494SG', 'Stratford', '070-494593', '6524');
INSERT INTO PLAYERS VALUES (104, 'Moorman', 'D', '1970-05-10', 'F', 1984, 'Stout Street','65', '9437AO', 'Eltham', '079-987571', '7060');
INSERT INTO PLAYERS VALUES (112, 'Bailey', 'IP', '1963-10-01', 'F', 1984, 'Vixen Road','8', '6392LK', 'Plymouth', '010-548745', '1319');

INSERT INTO PENALTIES VALUES (1,  6, '1980-12-08',100);
INSERT INTO PENALTIES VALUES (2, 44, '1981-05-05', 75);
INSERT INTO PENALTIES VALUES (3, 27, '1983-09-10',100);
INSERT INTO PENALTIES VALUES (4,104, '1984-12-08', 50);
INSERT INTO PENALTIES VALUES (5, 44, '1980-12-08', 25);
INSERT INTO PENALTIES VALUES (6,  8, '1980-12-08', 25);
INSERT INTO PENALTIES VALUES (7, 44, '1982-12-30', 30);
INSERT INTO PENALTIES VALUES (8, 27, '1984-11-12', 75);

效果如图:
1.players
在这里插入图片描述
2.penalties
在这里插入图片描述

3.(案例01)表子查询

(1)目的.获取编号小于10的男性球员的号码(使用表子查询)
(2)图

在这里插入图片描述
(3)代码

SELECT `playersInner`.`PLAYERNO` AS 球员的号码
FROM (
	SELECT `PLAYERNO`
	FROM `players` 
	WHERE `PLAYERNO` < 10 AND `SEX` = "M"
) AS playersInner ;
  • 1.from 嵌套表必须使用 as给表名字,并且在第一行 select 的时候也不能使用原来的表指定(可以使用给名字的名字)
  • 2.from里面的select是一个 n*n 的表所以叫做表子查询
SELECT `PLAYERNO`
	FROM `players` 
	WHERE `PLAYERNO` < 10 AND `SEX` = "M"
  • 3.效果
    在这里插入图片描述

(4)(**重点)**复习一下select语法组成

select 
【字段】
from 
【表】
join 
【(可选)添加的其他表】 -- 1.联合查询
on
【(可选)添加其他表的条件】
where
【(可选)满足的条件】-- 2,条件查询
group by 
【(可选)分组】 -- 3.分组
having 
【(可选)分组的次要条件】
order by
【排序规则】  -- 4.排序
limit 
【分页】-- 5.分页

4.(案例02)行子查询

(1)要求:获取和100号球员性别相同并且居住在同一城市的球员号码。
(2)图:
在这里插入图片描述
(3)代码

-- 要求:获取和100号球员性别相同并且居住在同一城市的球员号码。

SELECT `PLAYERNO` AS 球员号码
FROM `players`
WHERE (`SEX`,`TOWN`) = (
SELECT `SEX`,`TOWN`
FROM `players`
WHERE `PLAYERNO` = 100);
  • 1。where 里面 代表了一行所以叫做 行子查询
  • 2.效果
    在这里插入图片描述

5.(案例03)标量子查询

(1)要求:获取和27号球员出生在同一年的球员的号码
(2)图:
在这里插入图片描述
(3)代码

-- (03练习标量子查询) 获取和27号球员出生在同一年的球员的号码
SELECT `PLAYERNO` AS 球员号码
FROM `players`
WHERE YEAR(`BIRTH_DATE`)=(
	SELECT YEAR(`BIRTH_DATE`)
	FROM `players`
	WHERE `PLAYERNO` = 27)
AND `PLAYERNO` != 27;
  • 1。效果
    在这里插入图片描述

6.(案例04.1)列子查询 in

(1)要求:获取球员性别为女的所有球员的球员号,名字及所在城市。
(2)注意:因为结果是n行1列,所以不能使用 = >< != 等操作符(使用 in any (some)all替代)

操作符号 作用
in 在指定项里,in(项1,项2…)
any(some) 和比较操作符号联合使用,和 or 类似
all 接在比较操作符号的后面, 和 and 类似,

(3)代码

-- (04列子查询练习)获取性别为 女的所有的球员的球员号,名字和城市
SELECT `PLAYERNO` AS 球员号,`NAME` AS 名字,`TOWN` AS 城市
FROM `players`
WHERE `PLAYERNO` IN (
SELECT `PLAYERNO`
WHERE `SEX` = "F"
);
  • 1.因为 where 下的select语句的结果的时一个列,所以叫列子查询.
  • 2.效果:
    在这里插入图片描述

7.(案例04.2)列子查询 any

(1)要求:获取至少比同城的另一球员年轻的所有球员的手机号码,日期和居住城市
(2)代码

/*
#### 7.(案例04.2)列子查询
(1)要求:获取 至少比同城的另一球员年轻的所有球员 的号码,日期和居住城市
*/
SELECT `PHONENO` AS 号码,`BIRTH_DATE` AS 出生日期,`TOWN` AS 居住城市
FROM `players` AS p1
WHERE `BIRTH_DATE` > ANY(
SELECT `BIRTH_DATE`
FROM `players` AS p2
WHERE p2.`TOWN` = p1.`TOWN`
);

(3)效果

在这里插入图片描述

8.(案例04.3)列子查询 all

(1)目的:获取最老球员的号码,名字及生日。(即出生日期数值小于或等于所有其它球员的球员)
(2)代码

/*
#### 8.(案例04.3)列子查询 all 
(1)目的:获取最老球员的 学员号,名字及生日。(即出生日期数值小于或等于所有其它球员的球员)
*/
SELECT `PLAYERNO` AS 学员号,`NAME` AS 名字,`BIRTH_DATE` AS 生日
FROM `players`AS p1
WHERE p1.`BIRTH_DATE` <= ALL(
	SELECT p2.`BIRTH_DATE`
	FROM `players` AS p2 
);

(3)效果:
在这里插入图片描述
参考博客
https://blog.csdn.net/JesseYoung/article/details/40108781

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章