MYSQL学习笔记八(多表查询)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/merciaMA/article/details/97813561

一、子查询

子查询指一个查询语句嵌套在另一个查询语句内部的查询。子查询可以添加到 SELECT、UPDATE 和 DELETE 语句中,而且可以进行多层嵌套。子查询也可以使用比较运算符,如“<”、“<=”、“>”、“>=”、“!=”等。
常用的子查询如下表:

编号 子查询 说明
1 where子查询 把内层查询的结果作为外层查询的比较条件
2 from子查询 把内层的查询结果当成临时表,供外层sql再次查询。查询结果集可以当成表看待。临时表要使用一个别名。
3 exists型子查询 把外层sql的结果,拿到内层sql去测试,如果内层的sql成立,则该行取出。内层查询是exists后的查询。
4 any子查询 与比较操作符联合使用,表示与子查询返回的所有值比较都为 TRUE ,则返回 TRUE 。
5 in 子查询 在指定项内,同 IN(项1,项2,…)。

创建测试使用的表,并插入数据,其SQL命令如下:

#创建学生表
CREATE TABLE studentTable
(
studentNumber NVARCHAR(30),   #学生编号
fullname NVARCHAR(30),   #学生姓名
age INT #学生年龄
);

#创建学生成绩表
CREATE TABLE scoreTable  
(
ID INT,  #主键
studentNumber NVARCHAR(30),  #学生编号
subjectName NVARCHAR(30),  #课程名称
score INT # 成绩
)

###插入学生信息
INSERT INTO studentTable( studentNumber ,fullname,age)VALUES('001','coco',18);
INSERT INTO studentTable( studentNumber ,fullname,age)VALUES('002','merry',19);
INSERT INTO studentTable( studentNumber ,fullname,age)VALUES('003','mercia',20);
INSERT INTO studentTable( studentNumber ,fullname,age)VALUES('004','lili',21);

###插入数据
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(1,'002','英语',80);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(2,'002','数学',76);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(3,'002','理综',65);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(4,'003','英语',90);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(5,'003','数学',70);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(6,'003','理综',80);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(7,'004','英语',95);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(8,'004','数学',77);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(9,'004','理综',88);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(10,'001','英语',60);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(11,'001','数学',70);
INSERT INTO scoreTable(ID, studentNumber ,subjectName,score)VALUES(12,'001','理综',90);

1.1 where子查询

eg:查询总成绩最高的学生信息。sql语句如下:

SELECT * FROM studentTable 
WHERE studentNumber=(
SELECT studentNumber  FROM scoreTable
GROUP BY studentNumber
ORDER BY SUM(score) DESC LIMIT 1)

执行结果如下:
在这里插入图片描述

1.2 from子查询

eg:获取理综、数学、英语各科最高成绩的和。SQL命令如下:

SELECT SUM(score1) FROM (
SELECT subjectName,MAX(score) score1  FROM scoreTable 
GROUP BY subjectName
) AS a

在这里插入图片描述

1.3 exists子查询

exists直接结合where来使用。所以经常看到的是where exists或where not exists,其作用是判断后面面语句执行结果是否为真。
where exists:后续子句中如果为真,则将执行where之前的语句。
eg:如果scoreTable 表中有score(成绩)大于85的,则显示所有的成绩信息,sql语句如下:

SELECT * FROM scoreTable 
WHERE EXISTS (SELECT * FROM scoreTable WHERE score>85)

运行结果如下:
在这里插入图片描述
where not exists:后续子句中如果不为真,则将执行where之前的语句。
eg:如果scoreTable 表中没有score(成绩)大于95的,则显示所有的成绩信息,sql语句如下:

SELECT * FROM scoreTable 
WHERE NOT EXISTS (SELECT * FROM scoreTable WHERE score>95)

执行结果:
在这里插入图片描述

1.4 any子查询

eg:查询至少有一科成绩大于85的所有学生信息,sql语句如下:

SELECT * FROM studentTable 
WHERE  studentNumber = ANY (SELECT studentNumber FROM scoreTable WHERE score>85)

执行结果如下:
在这里插入图片描述

扫描二维码关注公众号,回复: 7600849 查看本文章

1.5 in 子查询

in和any比较类似,这里还用any的demo来进行说明:
eg:查询至少有一科成绩大于85的所有学生信息,sql语句如下:

SELECT * FROM studentTable 
WHERE  studentNumber IN (SELECT studentNumber FROM scoreTable WHERE score>85) 

执行结果如下:
在这里插入图片描述
in:where条件中设置的字段的值,在子句的结果集中。
not in :where条件中设置的字段的值,不在子句的结果集中。

1.6 exists与in

  • in所对应的select语句返回的结果一定是一列!可以为多行。
  • exists的条件就像一个boolean条件,当能返回结果集则为1,不能返回结果集则为 0。
  • not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;
  • 而not extsts 的子查询依然能用到表上的索引。
  • 用not exists要比not in要快。

二 、连接查询

连接查询,也为多表查询。这里以两个简单的表为例。
在这里插入图片描述
SQL语句如下:

##创建A表
CREATE TABLE A
(
aID INT,
aNAME NVARCHAR(30)
);

##创建B表
CREATE TABLE B
(
bID INT,
bNAME NVARCHAR(30),
aID INT
);

##插入数据
INSERT INTO A(aID, aNAME )VALUES(1,'AA1');
INSERT INTO A(aID, aNAME )VALUES(2,'AA3');
INSERT INTO B(bID, bNAME,aID )VALUES(1,'BB1',1);
INSERT INTO B(bID, bNAME,aID )VALUES(2,'BB2',1);
INSERT INTO B(bID, bNAME,aID )VALUES(3,'BB3',2);

2.1 交叉连接(cross join)

CROSS JOIN子句从连接的表返回行的笛卡儿乘积。
交叉连接就是指,加入有两个表,使用交叉连接查询的结果是两个表中的数据会进行完全匹配和交叉。如下图,使用交叉连接产生的数据条数是2*3一共6条数据。如果A表3条数据,B表3条数据,则查询结果会是9条数据。
在这里插入图片描述
eg,这是使用交叉连接查询A表和B表的数据,sql语句如下:

#写法一:
SELECT * FROM  A  CROSS JOIN B
#写法二:
 SELECT * FROM  A , B

执行结果如下:
在这里插入图片描述

2.2 内连接(inner join)

分别给A表和B表插入两条数据,sql脚本为:
在这里插入图片描述
INSERT INTO A(aID, aNAME )VALUES(3,‘AA3’);
INSERT INTO B(bID, bNAME,aID )VALUES(4,‘BB4’,4);
内连接可以理解为两证表中同时符合主外键业务的数据组合。如下图:
在这里插入图片描述
使用内连接查询A表和B表的数据,sql语句如下:

   SELECT * FROM A INNER JOIN B
   ON A.`aID`=B.`aID`

执行结果如下:
在这里插入图片描述

2.3 左连接(left join)

在这里插入图片描述
左连接是以左侧的数据表为主,右侧没有对应数据时,用null填充。进行数据展示:
在这里插入图片描述
使用左连接查询A表和B表的数据,sql语句如下:

SELECT * FROM A LEFT JOIN B
ON A.`aID`=B.`aID`

执行结果如下:
在这里插入图片描述

2.4 右连接(right join)

在这里插入图片描述
右连接与左连接类似,右连接查询数据以右侧表为主,左侧表中没有对应数据用null进行填充。
在这里插入图片描述
使用右连接查询A表和B表的数据,sql语句如下:

SELECT * FROM A RIGHT JOIN B
ON A.`aID`=B.`aID`

执行结果如下:
在这里插入图片描述

2.5 联合查询(union与union all)

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
注意事项:
UNION 内部的 SELECT 语句必须拥有相同数量的列。
列也必须拥有相似的数据类型。
同时,每条 SELECT 语句中的列的顺序必须相同。
语法结构如下:

SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2

eg :
使用UNION 查询A表和B表的数据,sql语句如下:

SELECT aNAME  FROM A
UNION
SELECT bNAME  FROM B

执行结果如下:
在这里插入图片描述
默认UNION 查询结果为不重复的值。如果允许重复的值,请使用 UNION ALL。
UNION ALL的语法结构:

SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2

eg :
使用UNION ALL查询A表和B表的数据,sql语句如下:

SELECT aNAME  FROM A
UNION ALL
SELECT bNAME  FROM B

执行结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/merciaMA/article/details/97813561