mysql初识(六) 多表关联

/**
mysql 多表关联

*/

一对一的关联 比如城市和区号的关联*******************

先是一个city表
cid city coid
1 北京 1
2 上海 2
3 广州 3

再一个区号表
coid code
1 010
2 020
3 0755

这样通过 cid和coid的关联将两张表连在一起
一对一的类型 他的关联字段可以随便放在两个表中
mysql> select * from city,code where city.coid=code.coid;
+-----+------+------+------+------+
| cid | city | coid | coid | code |
+-----+------+------+------+------+
| 1 | 北京 | 1 | 1 | 010 |
| 2 | 上海 | 2 | 2 | 020 |
| 3 | 广州 | 3 | 3 | 0755 |
+-----+------+------+------+------+

一对N的关联 比如说学生和班级的关联***************
一个学生表
mysql> select * from student;
+----+------------+------+------+-------+
| id | name | sex | age | class |
+----+------------+------+------+-------+
| 1 | 小明 | 男 | 14 | 1 |
| 2 | 李雷 | 男 | 14 | 1 |
| 3 | 韩梅梅 | 女 | 20 | 1 |
| 4 | aboy | 男 | 10 | 1 |
| 6 | 小明 | 男 | 14 | 1 |
| 7 | 李大锤 | 女 | 17 | 2 |
| 8 | MrJoker | 男 | 42 | 2 |
| 9 | mingzdi | 男 | 19 | 2 |
| 10 | 新人 | 男 | 20 | 2 |
| 11 | 又一个新人 | 女 | 22 | 2 |
| 12 | newboy | 男 | 19 | 3 |
| 13 | oldboy | 男 | 19 | 1 |
| 14 | as | 男 | 17 | 3 |
+----+------------+------+------+-------+

一个班级表
mysql> select * from class;
+-----+-----------+
| cid | classname |
+-----+-----------+
| 1 | 一班 |
| 2 | 二班 |
| 3 | 三班 |
| 4 | 四班 |
+-----+-----------+

一对多的关联表关联条件给多的那一方

查出每个人对应的班级
select * from student,class where student.class=class.cid;

用内部链接的方法 inner join ******************
select * from student as s inner join class as c on s.class=c.cid;
on 是配合inner join 使用 进行条件限制

找到二班的全部同学
select * from student as s inner join class as c on s.class=c.cid where class="2";

左关联和右关联****************************************
左关联
mysql> select * from student as s left join class as c on s.class=c.cid;
+----+------------+------+------+-------+------+-----------+
| id | name | sex | age | class | cid | classname |
+----+------------+------+------+-------+------+-----------+
| 1 | 小明 | 男 | 14 | 1 | 1 | 一班 |
| 2 | 李雷 | 男 | 14 | 1 | 1 | 一班 |
| 3 | 韩梅梅 | 女 | 20 | 1 | 1 | 一班 |
| 4 | aboy | 男 | 10 | 1 | 1 | 一班 |
| 6 | 小明 | 男 | 14 | 1 | 1 | 一班 |
| 7 | 李大锤 | 女 | 17 | 2 | 2 | 二班 |
| 8 | MrJoker | 男 | 42 | 2 | 2 | 二班 |
| 9 | mingzdi | 男 | 19 | 2 | 2 | 二班 |
| 10 | 新人 | 男 | 20 | 2 | 2 | 二班 |
| 11 | 又一个新人 | 女 | 22 | 2 | 2 | 二班 |
| 12 | newboy | 男 | 19 | 3 | 3 | 三班 |
| 13 | oldboy | 男 | 19 | 1 | 1 | 一班 |
| 14 | as | 男 | 17 | 3 | 3 | 三班 |
+----+------------+------+------+-------+------+-----------+
右关联
mysql> select * from student as s right join class as c on s.class=c.cid;
+------+------------+------+------+-------+-----+-----------+
| id | name | sex | age | class | cid | classname |
+------+------------+------+------+-------+-----+-----------+
| 1 | 小明 | 男 | 14 | 1 | 1 | 一班 |
| 2 | 李雷 | 男 | 14 | 1 | 1 | 一班 |
| 3 | 韩梅梅 | 女 | 20 | 1 | 1 | 一班 |
| 4 | aboy | 男 | 10 | 1 | 1 | 一班 |
| 6 | 小明 | 男 | 14 | 1 | 1 | 一班 |
| 13 | oldboy | 男 | 19 | 1 | 1 | 一班 |
| 7 | 李大锤 | 女 | 17 | 2 | 2 | 二班 |
| 8 | MrJoker | 男 | 42 | 2 | 2 | 二班 |
| 9 | mingzdi | 男 | 19 | 2 | 2 | 二班 |
| 10 | 新人 | 男 | 20 | 2 | 2 | 二班 |
| 11 | 又一个新人 | 女 | 22 | 2 | 2 | 二班 |
| 12 | newboy | 男 | 19 | 3 | 3 | 三班 |
| 14 | as | 男 | 17 | 3 | 3 | 三班 |
| NULL | NULL | NULL | NULL | NULL | 4 | 四班 |
+------+------------+------+------+-------+-----+-----------+

通过以上可以看出
在左关联时 左表student是全部显示,而没有人的四班是不会显示的
右关联时 右表class是全部显示 没有人的四班也会显示出来
通过以上总结出:向哪个表关联则哪个表的数据全部显示,另一个表全部去配合被关联的表

统计每个班级有多少人
mysql> select count(*),c.classname from student as s inner join class as c on s.
class=c.cid group by c.classname;
+----------+-----------+
| count(*) | classname |
+----------+-----------+
| 6 | 一班 |
| 2 | 三班 |
| 5 | 二班 |
+----------+-----------+
遇见
这个语句有三个关键点:
1.count(*) 是计算信息总数
2.inner join 将多表关联起来 on设置关联条件
3.group by 将表通过某信息分组

查找和李雷同班的同学
分三个步骤
1.先查出李雷对应的班级
mysql> select class from student where name=‘李雷‘; //是1
2.再查出李雷班级的所有同学
mysql> select * from student where class="1";
3.将李雷去除
mysql> select * from student where class="1" and name !=‘李雷‘;

将以上合并成一条数据就是:
select * from student where class=(select class from student where name=‘李雷‘) and name !=‘李雷‘;

多表关联***********************************
创建文章表 article
+-----+----------------+
| aid | title |
+-----+----------------+
| 1 | 百度上市了 |
| 2 | 明天开始放假了 |
| 3 | 周末不休息 |
| 4 | 明天上午上课 |
| 5 | 黄晓明离婚了 |
+-----+----------------+
创建中间表
+------+------+
| aid | tid |
+------+------+
| 1 | 2 |
| 1 | 1 |
| 1 | 3 |
| 2 | 2 |
| 2 | 3 |
| 3 | 3 |
| 4 | 4 |
| 4 | 3 |
| 5 | 1 |
| 5 | 2 |
| 5 | 3 |
+------+------+
创建标签表
+-----+-------+
| tid | tname |
+-----+-------+
| 1 | 热门 |
| 2 | 火爆 |
| 3 | 赞 |
| 4 | 苦恼 |
| 5 | 生气 |
+-----+-------+

三张表关联的基本思路是 (检索出所有文章对应的标签名)
select * from article as a join arc_tag as at on a.aid=at.aid join tag as t on at.tid=t.tid;

检索出文章对应的标签名
select * from article as a join art_tag as at on a.aid=at.aid;
+-----+----------------+------+------+
| aid | title | aid | tid |
+-----+----------------+------+------+
| 1 | 百度上市了 | 1 | 2 |
| 1 | 百度上市了 | 1 | 1 |
| 1 | 百度上市了 | 1 | 3 |
| 2 | 明天开始放假了 | 2 | 2 |
| 2 | 明天开始放假了 | 2 | 3 |
| 3 | 周末不休息 | 3 | 3 |
| 4 | 明天上午上课 | 4 | 4 |
| 4 | 明天上午上课 | 4 | 3 |
| 5 | 黄晓明离婚了 | 5 | 1 |
| 5 | 黄晓明离婚了 | 5 | 2 |
| 5 | 黄晓明离婚了 | 5 | 3 |
+-----+----------------+------+------+

检索出百度对应的标签名
mysql> select * from article as a join arc_tag as at on a.aid=at.aid join tag as t on at.tid=t.tid where title like ‘%百度%‘;
+-----+--------------+------+------+-----+-------+
| aid | title | aid | tid | tid | tname |
+-----+--------------+------+------+-----+-------+
| 1 | 百度上市了 | 1 | 1 | 1 | 热门 |
| 1 | 百度上市了 | 1 | 2 | 2 | 火爆 |
| 1 | 百度上市了 | 1 | 3 | 3 | 赞 |
+-----+--------------+------+------+-----+-------+

检索出和‘百度’拥有一样标签的文章
先检索出百度对应的标签id
select at.tid from article as a join arc_tag as at on a.aid=at.aid where a.title like ‘%百度%‘;
+------+
| tid |
+------+
| 2 |
| 1 |
| 3 |
+------+
再将这个作为条件进行查询 顺便将百度对应的文章屏蔽
mysql> select * from article as a join arc_tag as at on a.aid=at.aid join tag as t on at.tid=t.tid where at.tid in (1,2,3) and a.aid !=1;
+-----+----------------+------+------+-----+-------+
| aid | title | aid | tid | tid | tname |
+-----+----------------+------+------+-----+-------+
| 5 | 黄晓明离婚了 | 5 | 1 | 1 | 热门 |
| 2 | 明天开始放假了 | 2 | 2 | 2 | 火爆 |
| 5 | 黄晓明离婚了 | 5 | 2 | 2 | 火爆 |
| 2 | 明天开始放假了 | 2 | 3 | 3 | 赞 |
| 3 | 周末不休息 | 3 | 3 | 3 | 赞 |
| 4 | 明天上午上课 | 4 | 3 | 3 | 赞 |
| 5 | 黄晓明离婚了 | 5 | 3 | 3 | 赞 |
+-----+----------------+------+------+-----+-------+

将以上两条结合在一起就是个完整的语句
select * from article as a join arc_tag as at on a.aid=at.aid join tag as t on t.tid=at.tid where at.tid in (select at.tid from article as a join arc_tag as at on a.aid=at.aid where a.title like ‘%百度%‘) and a.title not like ‘%百度%‘;
+-----+----------------+------+------+-----+-------+
| aid | title | aid | tid | tid | tname |
+-----+----------------+------+------+-----+-------+
| 5 | 黄晓明离婚了 | 5 | 1 | 1 | 热门 |
| 2 | 明天开始放假了 | 2 | 2 | 2 | 火爆 |
| 5 | 黄晓明离婚了 | 5 | 2 | 2 | 火爆 |
| 2 | 明天开始放假了 | 2 | 3 | 3 | 赞 |
| 3 | 周末不休息 | 3 | 3 | 3 | 赞 |
| 4 | 明天上午上课 | 4 | 3 | 3 | 赞 |
| 5 | 黄晓明离婚了 | 5 | 3 | 3 | 赞 |
+-----+----------------+------+------+-----+-------+

检索出每个标签对应文章的数量
select count(*),tname from article as a join arc_tag as at on a.aid=at.aid join tag as t on t.tid=at.tid group by tname;
+----------+-------+
| count(*) | tname |
+----------+-------+
| 3 | 火爆 |
| 2 | 热门 |
| 1 | 苦恼 |
| 5 | 赞 |
+----------+-------+

时间: 2024-11-10 14:04:24

mysql初识(六) 多表关联的相关文章

MySQL千万级多表关联SQL语句调优

本文不涉及复杂的底层数据结构,通过explain解释SQL,并根据可能出现的情况,来做具体的优化,使千万级表关联查询第一页结果能在2秒内完成(真实业务告警系统优化结果). 需要优化的查询:使用explain 出现了Using temporary: 有分页时出现了Using filesort则表示使用不了索引,需要根据下面的技巧来调整语句 rows过多,或者几乎是全表的记录数: key 是 (NULL): possible_keys 出现过多(待选)索引. 1.使用explain语法,对SQL进行

数据库MySQL中关于“多表关联更新”的那些事

在常见的sql中,我们经常在查询中进行多表关联查询,用的比较熟练.今天在开发中遇到一个实际业务场景是多表关联更新,一时不知所措.本着多学习的态度,没有直接写java代码去实现,终于把多表关联更新的sql弄清楚了.下面将实际业务场景进行简化,分别有person表和information表,最终目的是将 information表中的年龄更新到person表中的每个人的年龄.分别写了几个sql demo来把多表更新的知识理解透彻. 首先,在更新前,person表和information表分别如下: i

Mysql中实现多表关联查询更新操作

今天一下要记录一下才行了,每次都要去网上查找方法,每次都难找得要命 Mysql在更新某些字段的数据时,有时候会依据其他表的数据进行更新,需要通过关联后对不同的行更新不同的值,传统的update set没法实现,可以用下面的方法来实现 UPDATE `widetable_solr_field` a INNER JOIN `widetable_field_increat` b SET a.`compose` = b.`udf` WHERE a.`fname` = CONCAT('t',b.`tabl

BSEG 和其他六个表关系

BSEG和其他六个表关系 BSEG里两个字段SAKNR(总账科目),HKONT(总账账目)的区别 HKONT里放的是凭证真实的总帐科目,SAKNR放的是供应商或客户的统驭科目. 如果某凭证行项目不是统驭科目,则SAKNR是空的,如果你输入正常的统驭科目凭证,这两个字段是相同的, 但当你输入特殊总帐凭证时,SAKNR里存的是统驭科目,HKONT放的是特殊总帐科目 BSAS+BSIS+BSAK+BSIK+BSAD+BSID = BSEG BSAS │ BSIS ==>all GL documents

BSEG和BSIS、BSAS、BSID、BSAD、BSIK、BSAK六个表的关系(转)

BSEG和BSIS.BSAS.BSID.BSAD.BSIK.BSAK 六个表的关系 1.数据关系: BSAS+BSIS+BSAK+BSIK+BSAD+BSID = BSEG 2.六个表说明: cleared opened   BSAS BSIS ==>all GL documents BSAK BSIK ==>all AP documents BSAD BSID ==>all AR documents BSAS:总帐明细(已清帐)总账 BSIS:总帐明细(未清帐)总账 BSAD:应收明细

BSEG和BSIS、BSAS、BSID、BSAD、BSIK、BSAK 六个表的关系

BSEG和BSIS.BSAS.BSID.BSAD.BSIK.BSAK六个表的关系 1.数据关系: BSAS+BSIS+BSAK+BSIK+BSAD+BSID = BSEG 2.六个表说明: cleared opened   BSAS BSIS ==>all GL documents BSAK BSIK ==>all AP documents BSAD BSID ==>all AR documents BSAS:总帐明细(已清帐)总账 BSIS:总帐明细(未清帐)总账 BSAD:应收明细(

MySQL多表关联查询与存储过程

1.多表关联查询 --  **************关联查询(多表查询)**************** -- 需求:查询员工及其所在部门(显示员工姓名,部门名称) -- 1.1 交叉连接查询(不推荐.产生笛卡尔乘积现象:4 * 4=16,有些是重复记录) SELECT empName,deptName FROM employee,dept; -- 需求:查询员工及其所在部门(显示员工姓名,部门名称) -- 多表查询规则:1)确定查询哪些表   2)确定查询哪些字段   3)表与表之间连接条件

Oracle中如何实现Mysql的两表关联update操作

在看<MySQL 5.1参考手册>的时候,发现MySQL提供了一种两表关联update操作.原文如下: UPDATE items,month SET items.price=month.price WHERE items.id=month.id; 在MySQL中构造表验证了一下 mysql> select * from test; +------+--------+ | id | salary | +------+--------+ | 1 | 100 | | 2 | 200 | | 3

MySQL多表关联查询效率高点还是多次单表查询效率高,为什么?

MySQL多表关联查询效率高点还是多次单表查询效率高,为什么? <阿里巴巴JAVA开发手册>里面写超过三张表禁止join 这是为什么?这样的话那sql要怎么写? 原文地址:https://www.cnblogs.com/gotodsp/p/10090382.html