一、子查詢的定義
子查詢 sub query 查詢是建立在某個查詢結果的基礎之上(一條select 語句內(nèi)部包含了一條select語句)
二、 子查詢分類
分為兩種:
按位置分類, 按結果分類
- 按位置分類:
按子查詢(select語句)在外部查詢(select語句)中出現(xiàn)的位置分類
(1)from 子查詢,子查詢語句跟在from之后
(2)where 子查詢,子查詢語句出現(xiàn)在where 條件中
(3)exists 子查詢,子查詢語句出現(xiàn)在exists里面 - 按結果分類:
根據(jù)子查詢得到的數(shù)據(jù)進行分類:
(1)標量子查詢:子查詢得到的結果是一行一列
(2)列子查詢:子查詢得到結果是一列多行
(3)行子查詢:子查詢得到的結果是一行多列(或者多行多列)
(4)表子查詢:子查詢得到的結果是多行多列(出現(xiàn)的位置是在from之后,上面的(1)(2)(3)是出現(xiàn)在where之后)
2.1 標量子查詢
示例:
班級表
CREATE TABLE c_class(
id int PRIMARY KEY AUTO_INCREMENT,
c_name VARCHAR(20) not NULL,
room VARCHAR (20) not null
) charset utf8;
插入數(shù)據(jù):
INSERT INTO c_class VALUES(1,'PHP0710','A203'),(2,'PHP0710','A204');
創(chuàng)建學生表
CREATE TABLE c_student(
id int PRIMARY KEY AUTO_INCREMENT,
number VARCHAR (10) not null,
name VARCHAR (20) not null,
sex VARCHAR (2) not null,
age TINYINT NOT null,
c_id int not null
) charset utf8;
插入表
INSERT INTO c_student VALUES
(5,'it001','張云','男','18',1),
(2,'it002','李四','男','17',2),
(3,'it003','張揚','男','18',3),
(4,'it004','王梅','女','18',2);


需求:知道班級名為PHP0710,想獲取該班的所有學生
步驟一:確定數(shù)據(jù)源,獲取所有的學生
select * from c_student where c_id = ?
步驟二:獲取班級id ,可以通過名字確定
select id from c_class where c_name = 'PHP0710'
步驟三:組合
SELECT * from c_student where c_id = (SELECT id from c_class WHERE c_name = 'PHP0710');

結果,一行一列,滿足標量子查詢
2.2 列子查詢
需求:查詢所有班級在讀學生
步驟一:確定數(shù)據(jù)源:學生
select * from c_student where c_id in(?)
步驟二:確定所有有效班級的班級id
select id from c_class;
步驟三:組合
SELECT * from c_student where c_id in (SELECT id from c_class)

列子查詢返回的結果一行多列,需要用in作為匹配條件,其實在mysql中,還有幾個類似的條件:all some any
- =any <===> in
SELECT * from c_student where c_id =any (SELECT id from c_class)
- any<===>some
=all -- 全部
2.4 行子查詢
返回的結果可以是一行多列也可以是多行多列
需求:要求查處學生中年齡最大且身高最大的學生
步驟一:確定數(shù)據(jù)源
select * from c_student where age = ? and height = ?;
步驟二:確定最大的年齡,確定最大的身高
select max(age),max(height) from c_student;
步驟三:合并
select * from c_student
where age = (SELECT max(age) from c_student)
and
height = (SELECT max(height) FROM c_student);


注意,做如上的語句操作時,須保證年齡和升高最大值出現(xiàn)在同一個學生身上,才能查到.
行子查詢:構造行元素,由多個行元素構成
select * from c_student where
-- (age,height) 稱之為行元素
(age,height) = (SELECT max(age),MAX(height) from c_student);

2.5表子查詢
表子查詢返回的結果是多行多列的二維表,子查詢返回的結果當多二維表來使用
需求:找出每個班身高最高的學生
步驟一:
確定數(shù)據(jù)源,先將學生按照身高降序排列
select * from c_student orderby height desc;
步驟二:
從每個班選出第一個學生
select * from c_student group by c_id;
步驟三:
第一步查詢的結果作為步驟二的數(shù)據(jù)源進行處理
from 子查詢
select * from (select * from c_student ORDER BY height desc) as student GROUP BY c_id;


2.6 exsits 子查詢
用來判斷某些條件是否滿足,往往是跨表。exists 是接在where之后。
exists返回的結果只有兩個(不是boolean類型)0和1
需求:查看所有學生,前提是班級存在的學生
步驟一:確定數(shù)據(jù)源:
select * from c_student where ?;
步驟二:條件是否滿足
exists(select * from c_class);--是否成立
步驟三:
合并
select * from c_student where
exists
(select * from c_class);
select * from c_student where
exists
(select * from c_class where `c_id` =5);
