首先准备数据

有以下数据,三张表:role(角色表)、hero(英雄表)、skill(技能表),我们以英雄联盟的数据做示例

  • 一个hero对应一个role(我们这里暂定)
  • 一个role可以对应多个hero
  • 一个hero可以对应多个skill
  • 一个skill只能对应一个hero

DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`id` int NOT NULL AUTO_INCREMENT,
`Name` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
INSERT INTO `role` VALUES (1,'战士'),(2,'法师'),(3,'刺客'),(4,'坦克'),(5,'射手'),(6,'辅助'); DROP TABLE IF EXISTS `hero`;
CREATE TABLE `hero` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`title` varchar(45) NOT NULL,
`role_id` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
INSERT INTO `hero` VALUES (1,'赵信','德邦总管',1),(2,'安妮','黑暗之女',2),(3,'瑞兹','符文法师',2),(4,'卡特琳娜','不祥之刃',3); DROP TABLE IF EXISTS `skill`;
CREATE TABLE `skill` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`passive` varchar(45) NOT NULL DEFAULT '0',
`hero_id` int NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
INSERT INTO `skill` VALUES (1,'果决','1',1),(2,'三重爪击','0',1),(3,'风斩电刺','0',1),(4,'无畏冲锋','0',1),(5,'新月护卫','0',1),(6,'嗜火','1',2),(7,'碎裂之火','0',2),(8,'焚烧','0',2),(9,'熔岩护盾','0',2),(10,'提伯斯之怒','0',2),(11,'奥术专精','1',3),(12,'超负荷','0',3),(13,'符文禁锢','0',3),(14,'法术涌动','0',3),(15,'曲境折跃','0',3),(16,'贪婪','1',4),(17,'弹射之刃','0',4),(18,'伺机待发','0',4),(19,'瞬步','0',4),(20,'死亡莲华','0',4);

为什么需要join?

有时候我们需要同时获取两张表或三张表或更多表的信息,我们有两种方式:

比如我们要查出英雄是 安妮 的技能有哪些

1.我们可以先在hero表查询到安妮的信息,然后再去skill表查询技能信息,需要两次查询

2.我们可以使用join将两张表关联到一起,通过一次查询获取

简单来说,就是需要同时获取多张表的信息时需要用到sql的join

1.corss join(交叉连接、笛卡尔连接)

corss join可以对两张表进行笛卡尔积,任意的两张表或多张表都可以进行笛卡尔连接,哪怕这些表没有任何关系

我们现在对hero表和skill进行corss join

corss join的语法

SELECT * FROM hero CROSS JOIN skill;
SELECT * FROM hero,skill;
SELECT * FROM hero JOIN skill;

以上三种形式都可以生成笛卡尔积,产生的结果是两个表的信息合并在一起,数据条数就是两个表条数相乘

corss join的问题

  • 笛卡尔积是两张表中任意的数据组合
  • 真实情况中我们不会将两个表进行笛卡尔积的,因为这样是不符合实际业务意义的,它纯粹是一个数学上的概念。比如上图中 卡特琳娜、瑞兹、安妮是不应该有赵信的果决技能的
  • 一般情况下我们还会配合使用 on 或者 where 来做一些筛选
  • 笛卡尔积可以做2张以上表的合集

那如何将那些不符合我们业务逻辑的记录过滤掉呢?

  • 使用 on
SELECT * FROM hero CROSS JOIN skill on hero.id = skill.hero_id;
  • 使用 where
SELECT * FROM hero CROSS JOIN skill WHERE hero.id = skill.hero_id;

此时我们查询到的结果就是符合业务逻辑的

通常我们是不使用 corss join 加 on 或 where 进行查询的,一般我们会使用 inner join

2.inner join(内连接)

我们直接把上面的 cross join 更改为 inner join

select * from hero inner join skill

查询到的依然是一个笛卡尔积

加上 on 后

select * from hero inner join skill on hero.id = skill.hero_id;

查询到的和cross join加on的结果是一样的。

用inner join和cross join的结果都是一样的,那么它们有什么区别?

  • inner join和cross join从结果上来对比是没有区别的,inner join主要是和其他的join如left join来区别的
  • 两者在底层实现上还是有所区别的
  • 一般来说cross join只用来求笛卡尔积

为什么加了on就可以把错误的记录去掉呢

如下图所示,加了on只有,只会将 hero.id = skill.role_id 的数据挑选出来,错误的结果就被排除掉了

3.left join(左连接)和right join(右连接)

为了说明left join和right join,我们在数据库中插入四条数据

//英雄表新增两个英雄,但是没有对应的技能
INSERT INTO `LOL`.`hero` (`name`, `title`, `role_id`) VALUES ('艾希', '寒冰射手', '5');
INSERT INTO `LOL`.`hero` (`name`, `title`, `role_id`) VALUES ('索拉卡', '众星之子', '6');
//技能表新增两个技能,但是没有对应的英雄
INSERT INTO `LOL`.`skill` (`name`, `passive`) VALUES ('阿尔法突袭', '0');
INSERT INTO `LOL`.`skill` (`name`, `passive`) VALUES ('无极剑道', '0');

使用lefe join进行查询

select hero.name,skill.name from hero left join skill on hero.id = skill.hero_id;

以上语句查询,我们会得到如下结果:

没有技能的两个英雄,它所对应的技能为null

那么left join和inner join有什么区别呢?

区别就是left join会包含inner join的结果集,left join就是查询到 hero.id = skill.hero_id 的结果集再加上左表没有匹配到的结果集;left join是更偏重左表的,将左表里面没有匹配到的记录也会加入到结果集中

left join是确保左表中的列是一定存在的

使用right join查询

select hero.name,skill.name from hero right join skill on hero.id = skill.hero_id;

以上语句查询,我们会得到如下结果:

所以我们发现right join和left join是相反的,侧重于右表

4.outer join

有时候我们希望左表的记录和右表的记录都出现在结果集里,我们就可以使用outer join

但是我们发现mysql、sqlserver都没有 outer join这个语法,只有 left outer join 和right outer join

left outer join 查询的结果和 left join 一样

right outer join 查询的结果和 right join 一样

那我们应该如何 outer join 呢

答案是使用 union

select hero.name,skill.name from hero left join skill on hero.id = skill.hero_id
union
select hero.name,skill.name from hero right join skill on hero.id = skill.hero_id

上述查询会产生如下结果,这个结果是符合我们预期的

以上就是sql中各种join的语法与使用

sql中的join的更多相关文章

  1. SQL中inner join、outer join和cross join的区别

    对于SQL中inner join.outer join和cross join的区别简介:现有两张表,Table A 是左边的表.Table B 是右边的表.其各有四条记录,其中有两条记录name是相同 ...

  2. SQL中关于Join、Inner Join、Left Join、Right Join、Full Join、On、 Where区别

    前言: 今天主要的内容是要讲解SQL中关于Join.Inner Join.Left Join.Right Join.Full Join.On. Where区别和用法,不用我说其实前面的这些基本SQL语 ...

  3. 【转载】SQL中inner join、outer join和cross join的区别

    对于SQL中inner join.outer join和cross join的区别很多人不知道,我也是别人问起,才查找资料看了下,跟自己之前的认识差不多, 如果你使用join连表,缺陷的情况下是inn ...

  4. LINQ TO SQL 中的join(转帖)

    http://www.cnblogs.com/ASPNET2008/archive/2008/12/21/1358152.html join对于喜欢写SQL的朋友来说还是比较实用,也比较容易接受的东西 ...

  5. Access SQL中Left Join、Right Join和Inner Join的使用

    1.表结构 表A                                     表B 2.Left Join 示例:2.1 Select * From A left join B on A. ...

  6. SQL中的Join和Where的区别

    一.sql语句中left join.inner join中的on与where的区别 0.各种join操作的概念和作用 left join :左连接,返回左表中所有的记录以及右表中连接字段相等的记录. ...

  7. SQL中INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN区别

    sql中的连接查询有inner join(内连接).left join(左连接).right join(右连接).full join(全连接)四种方式,它们之间其实并没有太大区别,仅仅是查询出来的结果 ...

  8. SQL中的join操作总结(非常好)

    1.1.1 摘要 Join是关系型数据库系统的重要操作之一,SQL Server中包含的常用Join:内联接.外联接和交叉联接等.如果我们想在两个或以上的表获取其中从一个表中的行与另一个表中的行匹配的 ...

  9. SQL中的JOIN语法详解

    参考以下两篇博客: 第一个是 sql语法:inner join on, left join on, right join on详细使用方法 讲了 inner join, left join, righ ...

随机推荐

  1. 《MySQL必知必会》检索数据,排序检索数据(select ,* ,distinct ,limit , . , order by ,desc)

    <MySQL必知必会>检索数据,排序检索数据 1.检索数据 1.1 select 语句 为了使用SELECT检索表数据,必须至少给出两条信息一想选择什 么,以及从什么地方选择. 1.2 检 ...

  2. 了解JS压缩图片,这一篇就够了

    前言 公司的移动端业务需要在用户上传图片是由前端压缩图片大小,再上传到服务器,这样可以减少移动端上行流量,减少用户上传等待时长,优化用户体验. 插播一下,本文案例已整理成插件,已上传npm ,可通过 ...

  3. SpringSecurity权限管理系统实战—五、整合SpringSecurity(下)

    系列目录 前言 上篇文章SpringSecurity整合了一半,这次把另一半整完,所以本篇的序号接着上一篇. 七.自定义用户信息 前面我们登录都是用的指定的用户名和密码或者是springsecurit ...

  4. React 17 要来了,非常特别的一版

    写在前面 React 最近发布了v17.0.0-rc.0,距上一个大版本v16.0(发布于 2017/9/27)已经过去近 3 年了 与新特性云集的 React 16及先前的大版本相比,React 1 ...

  5. 《java多线程——线程简介与其创建(1)》

    Java 给多线程编程提供了内置的支持. 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 多线程是多任务的一种特别的形式,但多线程使用了更小的资源开 ...

  6. Hive学习目录

    大数据之Hive学习目录 第 1 章 Hive入门 1.1 什么是Hive 1.2 Hive的优缺点 1.2.1 优点 1.2.2 缺点 1.3 *Hive架构原理 1.4 Hive和数据库比较 第 ...

  7. Linux环境下安装MySQL数据库

    Linux安装mysql服务分两种安装方法: (1).源码安装,优点是安装包比较小,只有十多M,缺点是安装依赖的库多,安装编译时间长,安装步骤复杂容易出错: (2).使用官方编译好的二进制文件安装,优 ...

  8. 第一篇Scrum冲刺博客

    目录 一.Alpha 阶段认领的任务 二.明日成员的任务安排 三.整个项目预期的任务量 四.敏捷开发前的感想 五.团队期望 一.Alpha 阶段认领的任务 陈起廷 任务 预计时间 日记天气.心情选择 ...

  9. SPSSAU数据分析思维培养系列3:分析思路

    本文章为SPSSAU数据分析思维培养的第3期文章. 上文讲解如何选择正确的分析方法,除了有正确的分析方法外,还需要把分析方法进行灵活运用.拿到一份数据,应该如何进行分析,总共有几个步骤,第一步第二步应 ...

  10. javaweb中自己遇到的问题

    1.web中的编码问题 1.1服务器接收的数据 post请求,请求会在Servlet中进行解码,所以我们只需要对request设置UTF-8即可. request.setCharacterEncodi ...