134 MySQL多表查询

目录

  • 一、连表查询
  • 二、一对多的表关系
    • 2.1 数据准备
    • 2.2 笛卡尔积的概念
    • 2.3 内连接
    • 2.4 左连接
    • 2.5 右连接
    • 2.6 左右连接可以转换
    • 2.7 全连接
  • 三、一对一与一对多情况一致
  • 四、多对多的表连接

一、连表查询

  • 连接:将有联系的多张表通过关联(有联系就行,不一定是外键)字段,进行连接,形参一张大表
  • 连表查询:在大表的基础上进行查询,就称之为连表查询
  • 将表与表建立连接的方式有四种:内连接、左连接、右连接、全连接

二、一对多的表关系

2.1 数据准备

1.创建部门表
create table dep(
    id int primary key auto_increment,
    name varchar(16),
    work varchar(16)
);

2.创建员工表
create table emp(
    id int primary key auto_increment,
    name varchar(16),
    salary float,
    dep_id int
);

# 插入数据
insert into dep values(1, '市场部', '销售'), (2, '教学部', '授课'), (3, '管理部', '开车');
insert into emp(name, salary, dep_id) values('egon', 3.0, 2),('yanghuhu', 2.0, 2),('sanjiang', 10.0, 1),('owen', 88888.0, 2),('liujie', 8.0, 1),('yingjie', 1.2, 0);

###################cmd图示
mysql> select * from emp;
+----+----------+--------+--------+
| id | name     | salary | dep_id |
+----+----------+--------+--------+
|  1 | egon     |      3 |      2 |
|  2 | yanghuhu |      2 |      2 |
|  3 | sanjiang |     10 |      1 |
|  4 | owen     |  88888 |      2 |
|  5 | liujie   |      8 |      1 |
|  6 | yingjie  |    1.2 |      0 |
+----+----------+--------+--------+
6 rows in set (0.00 sec)

mysql> select * from dep;
+----+-----------+--------+
| id | name      | work   |
+----+-----------+--------+
|  1 | 市场部    | 销售   |
|  2 | 教学部    | 授课   |
|  3 | 管理部    | 开车   |
+----+-----------+--------+
3 rows in set (0.00 sec)

2.2 笛卡尔积的概念

笛卡尔积: 集合 X{a, b} * Y{o, p, q} => Z{{a, o}, {a, p}, {a, q}, {b, o}, {b, p}, {b, q}}

mysql>: select * from emp, dep;

总结:是两张表 记录的所有排列组合,数据没有利用价值

2.3 内连接

1.关键字:inner join on
2.语法:from A表 inner join B表 on A表.关联字段=B表.关联字段

select
    emp.id,emp.name,salary,dep.name,work
from emp inner join dep on emp.dep_id = dep.id
order by emp.id;
#######################cmd 图解
mysql> select
            emp.id,
            emp.name
            salary,
            dep.name,
            work
            from emp join dep on emp.dep_id=dep.id
            order by emp.id;
+----+----------+-----------+--------+
| id | salary   | name      | work   |
+----+----------+-----------+--------+
|  1 | egon     | 教学部    | 授课   |
|  2 | yanghuhu | 教学部    | 授课   |
|  3 | sanjiang | 市场部    | 销售   |
|  4 | owen     | 教学部    | 授课   |
|  5 | liujie   | 市场部    | 销售   |
+----+----------+-----------+--------+

# 总结:只保留两个表有关联的数据

2.4 左连接

1.关键字:left join on
2.语法:from 左表 left join 右表 on 左表.关联字段=右表.关联字段

select
    emp.id,emp.name,salary,dep.name,work
from emp left join dep on emp.dep_id = dep.id
order by emp.id;
###################cmd 图解
mysql> select
    -> emp.id,emp.name,salary,dep.name,work
    ->     from emp left join dep on emp.dep_id = dep.id order by emp.id;
+----+----------+--------+-----------+--------+
| id | name     | salary | name      | work   |
+----+----------+--------+-----------+--------+
|  1 | egon     |      3 | 教学部    | 授课   |
|  2 | yanghuhu |      2 | 教学部    | 授课   |
|  3 | sanjiang |     10 | 市场部    | 销售   |
|  4 | owen     |  88888 | 教学部    | 授课   |
|  5 | liujie   |      8 | 市场部    | 销售   |
|  6 | yingjie  |    1.2 | NULL      | NULL   |
+----+----------+--------+-----------+--------+

# 总结:保留左表的全部数据,右表有对应数据直接连表显示,没有对应关系空填充

2.5 右连接

1.关键字:right join on
2.语法:from A表 right join B表 on A表.关联字段=B表关联字段

select
    emp.id,emp.name,salary,dep.name,work
from emp right join dep on emp.dep_id = dep.id
order by emp.id;

#######################cmd 图解
mysql> select
    -> emp.id,emp.name,salary,dep.name,work
    -> from emp right join dep on emp.dep_id = dep.id
    -> order by emp.id;
+------+----------+--------+-----------+--------+
| id   | name     | salary | name      | work   |
+------+----------+--------+-----------+--------+
| NULL | NULL     |   NULL | 管理部    | 开车   |
|    1 | egon     |      3 | 教学部    | 授课   |
|    2 | yanghuhu |      2 | 教学部    | 授课   |
|    3 | sanjiang |     10 | 市场部    | 销售   |
|    4 | owen     |  88888 | 教学部    | 授课   |
|    5 | liujie   |      8 | 市场部    | 销售   |
+------+----------+--------+-----------+--------+

# 总结:保留右表的全部数据,左表有对应数据直接连表显示,没有对应关系空填充

2.6 左右连接可以转换

1.left左边的是左表,右边的是右表
2.right左边的是左表,右边的是右表
3.所以我们交换左右表的位置也是可以的   

select
    emp.id,emp.name,salary,dep.name,work
from emp right join dep on emp.dep_id = dep.id
order by emp.id;

mysql>:
select
    emp.id,emp.name,salary,dep.name,work
from dep left join emp on emp.dep_id = dep.id
order by emp.id;

# 总结:更换一下左右表的位置,相对应更换左右连接关键字,结果相同

2.7 全连接

1.就是先把两张表进行左连接,中间加一个关键字union, 然后再进行右链接
select
    emp.id,emp.name,salary,dep.name,work
from emp left join dep on emp.dep_id = dep.id 

union

select
    emp.id,emp.name,salary,dep.name,work
from emp right join dep on emp.dep_id = dep.id 

order by id;

###############################cmd 图示
mysql> select
    -> emp.id,emp.name,salary,dep.name,work
    -> from emp left join dep on emp.dep_id = dep.id
    ->
    -> union
    ->
    -> select
    -> emp.id,emp.name,salary,dep.name,work
    -> from emp right join dep on emp.dep_id = dep.id
    ->
    -> order by id;
+------+----------+--------+-----------+--------+
| id   | name     | salary | name      | work   |
+------+----------+--------+-----------+--------+
| NULL | NULL     |   NULL | 管理部    | 开车   |
|    1 | egon     |      3 | 教学部    | 授课   |
|    2 | yanghuhu |      2 | 教学部    | 授课   |
|    3 | sanjiang |     10 | 市场部    | 销售   |
|    4 | owen     |  88888 | 教学部    | 授课   |
|    5 | liujie   |      8 | 市场部    | 销售   |
|    6 | yingjie  |    1.2 | NULL      | NULL   |
+------+----------+--------+-----------+--------+

# 总结:左表右表数据都被保留,彼此有对应关系正常显示,彼此没有对应关系均空填充对方

三、一对一与一对多情况一致

# 创建一对一 作者与作者详情 表
create table author(
    id int,
    name varchar(64),
    detail_id int
);
create table author_detail(
    id int,
    phone varchar(11)
);
# 填充数据
insert into author values(1, 'Bob', 1), (2, 'Tom', 2), (3, 'ruakei', 0);
insert into author_detail values(1, '13344556677'), (2, '14466779988'), (3, '12344332255');

# 内连
select author.id,name,phone from author join author_detail on author.detail_id = author_detail.id order by author.id;

# 全连(左连加外联)
select author.id,name,phone from author left join author_detail on author.detail_id = author_detail.id
union
select author.id,name,phone from author right join author_detail on author.detail_id = author_detail.id
order by id;

四、多对多的表连接

# 在一对一基础上,建立 作者与书 的多对多关系关系

# 利用之前的作者表
create table author(
    id int,
    name varchar(64),
    detail_id int
);
insert into author values(1, 'Bob', 1), (2, 'Tom', 2), (3, 'ruakei', 0);

# 创建新的书表
create table book(
    id int,
    name varchar(64),
    price decimal(5,2)
);
insert into book values(1, 'python', 3.66), (2, 'Linux', 2.66), (3, 'Go', 4.66);

# 创建 作者与书 的关系表
create table author_book(
    id int,
    author_id int,
    book_id int
);
# 数据:author-book:1-1,2  2-2,3  3-1,3
insert into author_book values(1,1,1),(2,1,2),(3,2,2),(4,2,3),(5,3,1),(6,3,3);

# 将有关联的表一一建立连接,查询所以自己所需字段
select book.name, book.price, author.name from book
join author_book on book.id = author_book.book_id
join author on author_book.author_id = author.id;

select book.name,book.price,author.name,author_detail.phone from book
join author_book on book.id =author_book.book_id
join author on author_book.author_id = author.id
left join author_detail on author.detail_id = author_detail.id

原文地址:https://www.cnblogs.com/xichenHome/p/11588408.html

时间: 2024-11-08 21:02:26

134 MySQL多表查询的相关文章

python3 mysql 多表查询

python3 mysql 多表查询 一.准备表 创建二张表: company.employee company.department #建表 create table department( id int, name varchar(20) ); create table employee( id int primary key auto_increment, name varchar(20), sex enum('male','female') not null default 'male'

MySQL多表查询回顾

----------------------siwuxie095 MySQL 多表查询回顾 以客户和联系人为例(一对多) 1.内连接 /*内连接写法一*/ select * from t_customer c,t_linkman l where c.cid=l.clid /*内连接写法二(inner 可以省略不写)*/ select * from t_customer c inner join t_linkman l on c.cid=l.clid 2.左外连接 /*左外连接(outer 可以省

mysql多表查询方法(left join(左连接),right join (右连接),inner join (内连接)的区别)

表A记录如下:  aID aNum  1 a20050111  2 a20050112  3 a20050113  4 a20050114  5 a20050115  表B记录如下:  bID bName  1 2006032401  2 2006032402  3 2006032403  4 2006032404  8 2006032408  创建这两个表SQL语句如下:  CREATE TABLE a  aID int( 1 ) AUTO_INCREMENT PRIMARY KEY ,  a

MySQL information_schema表查询导致内存暴涨

case:下面的一条sql语句,导致mysql实例内存暴涨: select * from tables where table_name not in(select table_name from partitions group by table_name having count(*)>1 ); mysql 5.5, 1w+的innodb表. 下面看下调查的结果: 1.  sql的执行情况以及内存分配:   step1: 构造information_schema.tables临时表 1.1 

MYSQL 连表查询及别名用法

MYSQL连表查询是两个表之间的查询或者更多表之间查询,通过外键的方式查询所有的数据,在查询过程中产生字段的重复,为了区分这种情况数据库设计别名,有的表很长,也可以用别名. 1,连表查询 INNER JOIN ,LEFT JOIN,RIGHT JOIN INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录.LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录.RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表

4 - MySQL:多表查询

MySQL:多表查询 一,介绍 本节主题 多表连接查询 复合条件连接查询 子查询 准备工作 #建表 create table department( id int, name varchar(20) ); create table employee( id int primary key auto_increment, name varchar(20), sex enum('male','female') not null default 'male', age int, dep_id int

记一次mysql多表查询(left jion)优化案例

一次mysql多表查询(left jion)优化案例 在新上线的供需模块中,发现某一个查询按钮点击后,出不来结果,找到该按钮对应sql手动执行,发现需要20-30秒才能出结果,所以服务端程序判断超时,故先不显示结果 以下是对这条查询的优化记录 1 数据库配置 数据库配置:4C8G 主表数据:3W+ 2 sql语句 提取sql语句,简化如下 SELECT taba.id, taba.title, taba.type, taba.end_time, tabb.username, tabc.orgna

python开发mysql:单表查询&多表查询

一 单表查询,以下是表内容 1 一 having 过滤 2 1.1 having和where 3 select * from emp where id > 15; 4 解析过程;from > where 找到数据 > 分组(没有默认一个组)> select 打印 where是出结果之前 5 select * from emp having id > 15; 6 解析过程;from > where 找到数据(没有约束条件,就是整个表)) > 分组(没有默认一个组)&

mysql联表查询,使用phpStudy自带的

一.内联结.外联结.左联结.右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结.2.外联结:分为外左联结和外右联结.左联结A.B表的意思就是将表A中的全部记录和表B中联结的字段与表A的联结字段符合联结条件的那些记录形成的记录集的联结,这里注意的是最后出来的记录集会包括表A的全部记录.右联结A.B表的结果和左联结B.A的结果是一样的,最后出来的记录集会包括表B的全部记录.具体如下: Select l