MySQL 连接查询、联合查询和子查询

准备测试数据

create table class(
	cid int(10),
	cdesc varchar(20)
);

create table student(
	sid int(10),
	name varchar(20),
	age int(3),
	cid int(10)
);

create table teacher(
	tid int(10),
	name varchar(20),
	cid int(10)
);

insert into class values(1, "PHP"),(2, "Java"),(3, "C++"),(4,"SQL");
insert into student values(1, "s1",16,1),(2, "s2",17,2),(3, "s3",18,3),(4,"s4",19,4),(5, "s5",18,3),(6,"s6",19,4);

insert into teacher values(1, "t1",1),(2, "t2",2),(3, "t3",3),(4,"t4",4);

alter table student add constraint sid_pk primary key(sid);

连接查询 join

连接查询方式有:内连接、外连接(常用,分为左连接和右连接)、自然连接、交叉连接。借助连接查询,可以同时查看多张表中的数据。

  • 内连接:有条件连接,用 on 在多个表之间指定条件连接。如果两个表的任一个匹配不到数据,则返回空
  • 外连接:有条件连接,用 on 在多个表之间指定条件连接。只要主表(左连接的左表,右连接的右表)匹配到数据,就不会返回空,未匹配到数据的字段填充 NULL
mysql> select * from class join student on student.cid = class.cid where class.cid = 1;
Empty set (0.00 sec)

mysql> select * from class left join student on student.cid = class.cid where class.cid = 1;
+-----+-------+------+------+------+------+
| cid | cdesc | sid  | name | age  | cid  |
+-----+-------+------+------+------+------+
|   1 | PHP   | NULL | NULL | NULL | NULL |
+-----+-------+------+------+------+------+
1 row in set (0.00 sec)

mysql> select * from student left join class on student.cid = class.cid where class.cid = 1;
Empty set (0.00 sec)

语法

  • 内连接:select 字段列表 from 左表 [inner] join 右表 on 左表.字段 = 右表.字段;
  • 外连接(重要):
    左外连接:select 字段列表 from 左表 left join 右表 on 左表.字段 = 右表.字段;
    右外连接:select 字段列表 from 左表 right join 右表 on 左表.字段 = 右表.字段;
  • 自然连接:有条件连接,但是不需要指定,MySQL 自动依据“同名字段”连接(多个同名字段就都作为条件)。
  • 交叉连接 cross join:无条件连接,取笛卡尔积,返回的记录数等于各表记录数的乘积。

联合查询 union

将多个查询结果进行拼接,多个查询结果的字段数必须相同,类型可以不同。支持两个选项:

  • all:不对相同结果去重,默认选项
  • distinct:去重
mysql> select age from student union distinct select cdesc from class;
+------+
| age  |
+------+
| 17   |
| 18   |
| 19   |
| C++  |
| Java |
| PHP  |
| SQL  |
+------+
7 rows in set (0.00 sec)

子查询

  • from 子查询:from 后面是子查询。注意这个子查询会创建临时表,需要为其起个别名:
mysql> select sid from (select * from student where sid > 2);
ERROR 1248 (42000): Every derived table must have its own alias
mysql> select sid from (select * from student where sid > 2) as s;
+-----+
| sid |
+-----+
|   3 |
|   4 |
|   5 |
|   6 |
+-----+
4 rows in set (0.00 sec)
  • where 子查询:where 后面是子查询。
mysql> select * from student where age > (select age from student where sid = 3);
+-----+------+------+------+
| sid | name | age  | cid  |
+-----+------+------+------+
|   4 | s4   |   19 |    4 |
|   6 | s6   |   19 |    4 |
+-----+------+------+------+
2 rows in set (0.00 sec)
  • where exists 子查询:where exists 后面是子查询。
mysql> select * from class where exists(select * from  student where cid=1);
Empty set (0.00 sec)

mysql> select * from class where exists(select * from  student where cid=2);
+-----+-------+
| cid | cdesc |
+-----+-------+
|   1 | PHP   |
|   2 | Java  |
|   3 | C++   |
|   4 | SQL   |
+-----+-------+
4 rows in set (0.00 sec)
发布了295 篇原创文章 · 获赞 158 · 访问量 101万+

猜你喜欢

转载自blog.csdn.net/kikajack/article/details/101075461