MySQL查询语句使用总结(二)——多表查询

MySQL查询语句使用总结(二)——多表查询

从表中查询所需要的数据使用select命令,select命令的语法如下:

select [distinct] 字段列表 [as 字段别名] 
from 数据源 [join 数据源 on 连接条件]   --多表连接查询
[where子句] 
[group by 子句] 
[having子句] 
[order by 子句] 
[limit子句];

一、数据准备: 创建三张表,student(学生)、course(课程)、score(成绩),命令如下:

create table student(
    s_id char(5) primary key comment '学生学号',
    s_name char(20) comment '学生姓名',
    age int comment '学生年龄',
    phone char(20) comment '电话',
    addr varchar(200) comment '家庭地址',
    class char(20) comment '班级'
);

create table course(
    c_id char(4) primary key comment '课程编号',
    c_name char(20) comment '课程名称',
    credits int comment '学分'
);

create table score(
    s_id char(5) comment '学生学号',
    c_id char(4) comment '课程编号',
    score int comment '成绩',
    primary key(s_id,c_id),
    foreign key(s_id) references student(s_id),
    foreign key(c_id) references course(c_id)
);

为以上三张表插入必要的数据,命令如下:

insert into student
values('S1001','张平',20,'15537302558','新乡市','物流1班'),('S1002','刘鹏',21,'15537306666','新乡市','物流1班'),
('S1003','张静静',18,'15937304444','新乡市','电商1班'),('S1004','刘宏伟',19,'15637306688','郑州市','电商1班'),
('S1005','张莹莹',19,'13937307888','开封市','电商1班'),('S1006','赵晶晶',18,'13503735522','安阳市','国贸1班');

insert into course
values('C001','数据库',4),('C002','数据结构',4),('C003','管理学',3),('C004','电子商务',3);

insert into score 
values('S1001','C001',80),('S1001','C002',90),('S1001','C004',87),
('S1002','C001',87),('S1002','C002',67),('S1002','C003',78),
('S1003','C001',66),('S1003','C002',77),('S1003','C003',88),('S1003','C004',99),
('S1004','C001',81),('S1004','C003',62),('S1004','C004',68);

二、笛卡儿积

笛卡儿积实现的是交叉连接(cross join),即两个表中的任意一行都进行连接。

--格式: select fieldlist from table1 cross join table2;
create table dept1(d_id int primary key,d_name char(20));
insert into dept1 values(101,'财务部'),(102,'销售部');
create table emp1(e_id int primary key,e_name char(20),age int);
insert into emp1 values(1,'张三',20),(2,'李四',23),(3,'王五',18),(4,'赵六',21);

mysql> select e_id,e_name,age,d_id,d_name from emp1 cross join dept1;
+------+--------+------+------+-----------+
| e_id | e_name | age  | d_id | d_name    |
+------+--------+------+------+-----------+
|    1 | 张三   |   20 |  101 | 财务部    |
|    1 | 张三   |   20 |  102 | 销售部    |
|    2 | 李四   |   23 |  101 | 财务部    |
|    2 | 李四   |   23 |  102 | 销售部    |
|    3 | 王五   |   18 |  101 | 财务部    |
|    3 | 王五   |   18 |  102 | 销售部    |
|    4 | 赵六   |   21 |  101 | 财务部    |
|    4 | 赵六   |   21 |  102 | 销售部    |
+------+--------+------+------+-----------+
8 rows in set (0.00 sec)

三、连接查询

连接查询本质上是从关系的笛卡尔积运算中再根据连接条件进行的选择运算。连接查询分为内连接(默认),左连接,右连接,完全连接。

1、内连接([inner] join):查询结果只包含满足连接条件的行。MySQL默认的连接方式就是内连接。格式为:

select fieldlist from table1 [inner] join table2
on table1.fieldname=table2.fieldname
where 查询条件;

举例:

mysql> select s.s_id,s_name,s.age,s.class,sc.c_id,sc.score
       from student s inner join score sc
       on s.s_id=sc.s_id;
+-------+-----------+------+------------+------+-------+
| s_id  | s_name    | age  | class      | c_id | score |
+-------+-----------+------+------------+------+-------+
| S1001 | 张平      |   20 | 物流1班    | C001 |    80 |
| S1001 | 张平      |   20 | 物流1班    | C002 |    90 |
| S1001 | 张平      |   20 | 物流1班    | C004 |    87 |
| S1002 | 刘鹏      |   21 | 物流1班    | C001 |    87 |
| S1002 | 刘鹏      |   21 | 物流1班    | C002 |    67 |
| S1002 | 刘鹏      |   21 | 物流1班    | C003 |    78 |
| S1003 | 张静静    |   18 | 电商1班    | C001 |    66 |
| S1003 | 张静静    |   18 | 电商1班    | C002 |    77 |
| S1003 | 张静静    |   18 | 电商1班    | C003 |    88 |
| S1003 | 张静静    |   18 | 电商1班    | C004 |    99 |
| S1004 | 刘宏伟    |   19 | 电商1班    | C001 |    81 |
| S1004 | 刘宏伟    |   19 | 电商1班    | C003 |    62 |
| S1004 | 刘宏伟    |   19 | 电商1班    | C004 |    68 |
+-------+-----------+------+------------+------+-------+
13 rows in set (0.00 sec)

2、外连接:内连接查询的结果只包含满足连接条件的数据,而外连接除了包含满足连接条件的数据,还包含左边的表或右边的表甚至两个表中的所有数据。MySQL的外连接只支持左连接和右连接,不支持完全连接。但可以使用关键字UNION来把左连接和右连接合并起来,以达到完全连接的效果。准备以下两个表演示外连接查询:

create table dept2(d_id int primary key,d_name char(20));
insert into dept2 values(101,'财务部'),(102,'销售部'),(103,'财务部');
create table emp2(e_id int primary key,e_name char(20),age int,d_id int);
insert into emp2 values(1,'张三',20,101),(2,'李四',23,101),(3,'王五',18,102),(4,'赵六',21,null);

(1)左外连接:左外连接是以左边表中的数据为基准,若左边表中有数据且右表中没有数据,则显示左边表中的数据,右边表中的数据显示为NULL。语法格式如下:

select fieldlist from table1 left [outer] join table2
on table1.fieldname=table2.fieldname
where 查询条件;

举例:

mysql> select e_id,e_name,age,dept2.d_id,d_name
       from emp2 left join dept2
       on emp2.d_id=dept2.d_id;
+------+--------+------+------+-----------+
| e_id | e_name | age  | d_id | d_name    |
+------+--------+------+------+-----------+
|    1 | 张三   |   20 |  101 | 财务部    |
|    2 | 李四   |   23 |  101 | 财务部    |
|    3 | 王五   |   18 |  102 | 销售部    |
|    4 | 赵六   |   21 | NULL | NULL      |
+------+--------+------+------+-----------+
4 rows in set (0.00 sec)

(2)右外连接:右外连接是以右边表中的数据为基准,若右边表中有数据且左表中没有数据,则显示右边表中的数据,左边表中的数据显示为NULL。语法格式如下:

select fieldlist from table1 right [outer] join table2
on table1.fieldname=table2.fieldname
where 查询条件;

举例:

mysql> select e_id,e_name,age,dept2.d_id,d_name
       from emp2 right join dept2
       on emp2.d_id=dept2.d_id;
+------+--------+------+------+-----------+
| e_id | e_name | age  | d_id | d_name    |
+------+--------+------+------+-----------+
|    1 | 张三   |   20 |  101 | 财务部    |
|    2 | 李四   |   23 |  101 | 财务部    |
|    3 | 王五   |   18 |  102 | 销售部    |
| NULL | NULL   | NULL |  103 | 财务部    |
+------+--------+------+------+-----------+
4 rows in set (0.00 sec)

(3)完全连接:MySQL的外连接只支持左连接和右连接,不支持完全连接。但可以使用关键字UNION来把左连接和右连接合并起来,以达到完全连接的效果。代码如下:

select e_id,e_name,age,dept2.d_id,d_name
       from emp2 left join dept2
       on emp2.d_id=dept2.d_id
union
select e_id,e_name,age,dept2.d_id,d_name
       from emp2 right join dept2
       on emp2.d_id=dept2.d_id;
+------+--------+------+------+-----------+
| e_id | e_name | age  | d_id | d_name    |
+------+--------+------+------+-----------+
|    1 | 张三   |   20 |  101 | 财务部    |
|    2 | 李四   |   23 |  101 | 财务部    |
|    3 | 王五   |   18 |  102 | 销售部    |
|    4 | 赵六   |   21 | NULL | NULL      |
| NULL | NULL   | NULL |  103 | 财务部    |
+------+--------+------+------+-----------+
5 rows in set (0.00 sec)

四、多表连接

多表连接指超过两张以上的表进行连接运算。语法格式如下:

select fieldlist from table1 [alias] 
[inner] join table2 [alias] on table1.fieldname=table2.fieldname
[inner] join table3 [alias] on table2.fieldname=table3.fieldname
...
where 查询条件;

举例:

mysql> select s.s_id,s_name,s.age,s.class,c.c_name,sc.c_id,sc.score
       from student s inner join score sc
       on s.s_id=sc.s_id inner join course c 
       on sc.c_id=c.c_id;
+-------+-----------+------+------------+--------------+------+-------+
| s_id  | s_name    | age  | class      | c_name       | c_id | score |
+-------+-----------+------+------------+--------------+------+-------+
| S1001 | 张平      |   20 | 物流1班    | 数据库       | C001 |    80 |
| S1002 | 刘鹏      |   21 | 物流1班    | 数据库       | C001 |    87 |
| S1003 | 张静静    |   18 | 电商1班    | 数据库       | C001 |    66 |
| S1004 | 刘宏伟    |   19 | 电商1班    | 数据库       | C001 |    81 |
| S1001 | 张平      |   20 | 物流1班    | 数据结构     | C002 |    90 |
| S1002 | 刘鹏      |   21 | 物流1班    | 数据结构     | C002 |    67 |
| S1003 | 张静静    |   18 | 电商1班    | 数据结构     | C002 |    77 |
| S1002 | 刘鹏      |   21 | 物流1班    | 管理学       | C003 |    78 |
| S1003 | 张静静    |   18 | 电商1班    | 管理学       | C003 |    88 |
| S1004 | 刘宏伟    |   19 | 电商1班    | 管理学       | C003 |    62 |
| S1001 | 张平      |   20 | 物流1班    | 电子商务     | C004 |    87 |
| S1003 | 张静静    |   18 | 电商1班    | 电子商务     | C004 |    99 |
| S1004 | 刘宏伟    |   19 | 电商1班    | 电子商务     | C004 |    68 |
+-------+-----------+------+------------+--------------+------+-------+
13 rows in set (0.00 sec)

五、自连接

自连接时连接的两张表是同一张表,通过别名进行区分,格式如下:

select fieldlist 
from table1 [alias1] [inner] join table1 [alias2] 
on alias1.fieldname=alias2.fieldname
where 查询条件;

举例:

create table emp3(e_id int primary key,e_name char(20),age int,leader_id int);
insert into emp3 values(1,'张三封',20,1),(2,'李四民',23,1),(3,'王小刚',18,1),
(4,'赵小六',21,2),(5,'陈小七',18,2),(6,'张小九',20,2);

mysql> select emp.*,leader.e_name as leader_name
       from emp3 emp inner join emp3 leader
       on leader.e_id=emp.leader_id;
+------+-----------+------+-----------+-------------+
| e_id | e_name    | age  | leader_id | leader_name |
+------+-----------+------+-----------+-------------+
|    1 | 张三封    |   20 |         1 | 张三封      |
|    2 | 李四民    |   23 |         1 | 张三封      |
|    3 | 王小刚    |   18 |         1 | 张三封      |
|    4 | 赵小六    |   21 |         2 | 李四民      |
|    5 | 陈小七    |   18 |         2 | 李四民      |
|    6 | 张小九    |   20 |         2 | 李四民      |
+------+-----------+------+-----------+-------------+
6 rows in set (0.00 sec)
发布了44 篇原创文章 · 获赞 48 · 访问量 5416

猜你喜欢

转载自blog.csdn.net/weixin_44377973/article/details/103114112
今日推荐