自连接讲解

news2024/9/30 1:43:58

什么是自连接?

        自连接可以理解为自己连接自己,在一张表上面所进行的操作;将一张表分成两张结构和数据完全一样的表,相当于克隆了一张跟自己长得一模一样的表;

 但是既然是两张一模一样的表,数据库怎么去区分出那张表是哪张表呢?这时候最重要的一个知识点就来了,那就是给两张表分别取个别名。

自连接语法

自连接我所知道有以下几种语法,有遗漏的话也欢迎大家在评论区给我补充出来。

1、内连接

1.1隐式内连接

select 字段列表 from 表 [as] 表别名1,表  [as]  表别名2 where 条件...;

1.2.显式内连接

select 字段列表 from 表  [as]  表别名1 [inner] join 表  [as]  表别名2 on 条件...;

2、外连接

2.1.左外连接

select 字段列表 from 表  [as]  表别名1 left [outer] join 表  [as]  表别名2 on 条件...;

2.2.右外连接

select 字段列表 from 表  [as]  表别名1 right [outer] join 表  [as]  表别名2 on 条件...;

温馨提示:[]里面的单词可以写,也可以省略不写。

案例演示1

商品表:

create table tb_goods(
    id int primary key auto_increment comment '主键ID',
    goods varchar(50) not null comment '商品',
    price decimal(7,2) default 0.00 comment '商品价格'
) comment '商品表';

给商品表插入数据:

insert into tb_goods(goods,price) values('儿童牙刷',20),
                                        ('电动牙刷',10000),
                                        ('拼多多牙刷',9.9);
insert into tb_goods(goods) values('妈妈给买的牙刷');

数据展示: 

需求:

查询比“拼多多牙刷”的价格贵的牙刷有哪些?

思路解析(用的是隐式内连接):

select 字段列表 from 表 [as] 表别名1,表  [as]  表别名2 where 条件...;

第一步:把 tb_goods(商品表)取两个别名,把它们连接起来;

select * from tb_goods as g1,tb_goods as g2;

查询结果如下:它会列出每条数据的组合情况,如下,每一种牙刷都能组成四种组合。

第二步:从 g1 表里面把所有“拼多多牙刷”找出来;
select * from tb_goods as g1,tb_goods as g2 where g1.goods = '拼多多牙刷';

查询结果如下:在 g1 表中找出了所有的“拼多多牙刷”。

可以看到 g2 表里面的 g2.price 已经把每个牙刷的价格都已经查询出来了;

第三步:这时候只要查询出 g2 的价格大于 g1 价格的数据就可以了,也就是大于“拼多多牙刷”的数据

select * from tb_goods as g1,tb_goods as g2 where g1.goods = '拼多多牙刷' and g2.price > g1.price;

查询结果如下:已经查出了 g2 的价格大于 g1 价格的数据。

第四步:此时就可以对这两个数据进行查询;

select g2.goods,g2.price from tb_goods as g1,tb_goods as g2 where g1.goods = '拼多多牙刷' and g2.price > g1.price;

查询结果如下:得到了比“拼多多牙刷”的价格贵的牙刷,已经完成了需求。

最后,如果要查询的数据更清晰的话,可以给查询的字段取别名;

select g2.goods as '商品',g2.price as '商品价格' from tb_goods as g1,tb_goods as g2 where g1.goods = '拼多多牙刷' and g2.price > g1.price;

查询结果如下:

同样的,用显示内连接也可以完成该需求:

select g2.* from tb_goods as g1 inner join tb_goods as g2 on g1.goods = '拼多多牙刷' and g2.price > g1.price;

查询结果如下:


案例演示2

学生表:

create table tb_student(
    id int primary key auto_increment comment '主键ID',
    student_id char(2) not null unique comment '学号',
    name varchar(50) not null comment '姓名',
    age tinyint unsigned not null comment '年龄',
    parent_id char(2) comment '监护人ID'
)comment '学生表';

给学生表插入数据:

insert into tb_student(student_id, name, age,parent_id) VALUES('01','大头儿子',6,'03'),
                                                              ('03','小头爸爸',31,null),
                                                              ('02','小灰灰',5,'04'),
                                                              ('04','灰太狼',36,null);

数据展示:  

需求:

1、查询 学生姓名 及 学生的监护人 姓名。

思路解析(用的是隐式内连接):

select 字段列表 from 表 [as] 表别名1,表  [as]  表别名2 where 条件...;

第一步:把 tb_student(学生表)取两个别名,把它们连接起来;

select * from tb_student as s1,tb_student as s2;

第二步:看到这个需求,你可能会觉得奇怪,为什么都没有 学生的监护人 这个字段,而只有 学生监护人ID ;

那是因为我们可以通过 学生监护人ID(parent_id) 关联 学生学号(student_id),找到该学生的学生监护人(student_id)。比如:大头儿子的 学生监护人ID(parent_id)是 03,此时 03 学生学号(student_id)的家长为 小头爸爸;

SQL 语句编写:找到 s1 表的 学生监护人ID(parent_id)和 s2 表的 学生学号(student_id),把它们用 = 关联起来,意思就是:通过 学生监护人ID(parent_id)找到 学生学号(student_id);

select * from tb_student as s1,tb_student as s2 where s1.parent_id = s2.student_id;

查询结果如下:此时就可以看到对应的 学生姓名(s1.name) 及 学生监护人姓名(s2.name) 都已经被找到了。

第三步:此时就可以对这两个数据进行查询;

select s1.name,s2.name from tb_student as s1,tb_student as s2 where s1.parent_id = s2.student_id;

查询结果如下:

最后,如果要查询的数据更清晰的话,可以给查询的字段取别名;

select s1.name as '学生姓名',s2.name as '学生监护人姓名' from tb_student as s1,tb_student as s2 where s1.parent_id = s2.student_id;

查询结果如下:

同样的,用显示内连接也可以完成该需求:

select s1.name '学生姓名',s2.name as '学生监护人姓名' from tb_student as s1 inner join tb_student s2 on s1.parent_id = s2.student_id;

查询结果如下:

还有一种情况,在这个学生表(tb_student)里面,还有人没有学生归属人,也就是学生归属人ID(parent_id)为 null 的情况;

此时,我提出了一个需求:我希望查询 学生姓名 及 学生的监护人 姓名,如果学生没有学生的监护人, 也要查询出来。

此时就不能使用内连接了,要使用外连接,内连接只能查出它们相互交集的数据;

select s1.name '学生姓名',s2.name '学生监护人姓名' from tb_student as s1 left join tb_student as s2 on s1.parent_id = s2.student_id;

查询结果如下:

完。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/149993.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[ 数据结构 ] 汉诺塔--------分治算法最佳实践

0 分治算法 分治法:是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。经典问题:…

什么你还不知道?快来看看我的年度总结吧

作者介绍:阿玥的小东东 作者职位:后端、python、正在学习c 主页:阿玥的小东东 现在呢,人们都在写自己的年度总结,我也来凑个热闹吧! 其实我来CSDN这个平台时间不算久,从2022年11月15号开始&…

<C++>set和map

文章目录1. 关联式容器2. 键值对3. 树形结构的关联式容器4. set4.1 set的介绍4.2 set的使用4.2.1 set的模板参数4.2.2 set的构造4.2.3 set的迭代器4.2.4 set的容量4.2.5 set修改操作4.2.6 set的使用举例5. multiset5.1 multiset的介绍5.2 multiset的使用6. map6.1 map的介绍6.2…

字符串相关类

文章目录一、String类String的介绍String实例化面试题:String snew String("abc")创建对象,在内存中创建了几个对象?易错题1易错题2String常用方法String与char[ ]之间的转换String与byte[ ]之间的转换二、StringBuffer类、StringB…

如何将NACOS作为配置中心

新建一个命名空间 点击创建配置 关键点1:Data ID的命名规则: 前面我们演示了在 nacos 控制台新建一个 DataID 为 cloud-producer-server-dev.yaml 的数据集,那么这个 Data ID 是什么呢?Data ID 是配置集的唯一标识,一个…

CSS初级教程(字体)【第七天】

文章目录【1】CSS 字体【2】CSS 字体样式【3】CSS 字体大小【4】CSS 谷歌字体【5】CSS 字体属性【6】所有 CSS 字体属性CSS上回学习链接 CSS初级教程 颜色【第一天】 CSS初级教程 背景【第二天】 CSS初级教程 边框【第三天】 CSS初级教程 边距、高度、宽度【第四天】 CSS初级教…

ChatGPT的注册和使用教程

1 简介在时下热门话题AI作画之外,最近一个名叫ChatGPT的聊天机器人又掀起了一股人工智能的热潮。已有无数人投入到对它的测试研究之中,想探清它到底无所不能到何种地步。据悉,已有超过百万人与机器人聊天,甚至导致网站一度崩溃。那…

URDF与RVIZ

#来自赵虚左的资料&#xff0c;视频 创建功能包urdf01_rviz&#xff0c;依赖rviz xacro(比较简单使用) <launch> <!-- 设置参数 --> <param name"robot_description" textfile"$(find urdf01_rviz)/urdf/urdf/demo01_helloworld.urdf"…

Docker软件安装文档

软件安装文档 文章目录软件安装文档虚拟机安装系统死锁问题JDK11安装Docker安装Docker-Compose安装MySQL安装MySQL8安装Docker-Compose安装MySQL8MySQL5.7安装Nacos安装Docker安装Nacos单机Docker-Compose安装Nacos集群OpenResty安装Redis安装Docker安装单机RedisDocker-Compos…

【Unity3D】点选物体、框选物体、绘制外边框

1 需求描述 点选物体&#xff1a;点击物体&#xff0c;可以选中物体&#xff0c;按住 Ctrl 追加选中&#xff0c;选中的物体设置为红色。框选物体&#xff1a;拖拽鼠标&#xff0c;屏幕上会出现滑动框&#xff0c;滑动框内的物体会被选中&#xff0c;选中的物体设置为红色。绘…

Vue中自定义指令是什么?有哪些应用场景?

一、什么是指令 开始之前先学习一下指令系统这个词 指令系统是计算机硬件的语言系统&#xff0c;也叫机器语言&#xff0c;它是系统程序员看到的计算机的主要属性。因此指令系统表征了计算机的基本功能决定了机器所要求的能力 在vue中提供了一套为数据驱动视图更为方便的操作&…

【C语言进阶】qsort函数详解以及它的模拟实现

目录一、qsort函数介绍二、qsort函数参数介绍2.1&#xff1a;void* base2.2&#xff1a;size_t num2.3&#xff1a;size_t size2.4&#xff1a;int(* compar)(const void *,const void *)三、实际应用3.1&#xff1a;利用qsort函数对整型数组排序3.2&#xff1a;利用qsort函数对…

2023年1月9日:fastadmin在列表操作列区域添加按钮及控制已有按钮显示

列表操作列区域添加按钮 buttons: [{name: detail,title: __(详情),classname: btn btn-xs btn-primary btn-dialog,icon: fa fa-list,url: audit/detail,callback: function (data) {Layer.alert("接收到回传数据&#xff1a;" JSON.stringify(data), {title: &q…

【nvivo11plus教程】01_nvivo介绍、案例与批注

1、查看nvivo版本2、nvivo是如何支持质性研究的3、nvivo的项目介绍4、建立nvivo项目(1)建立项目(2)文件夹(3)新建分类(4)建立备忘录5、案例(1)建立案例(2)案例节点分类的变量设置(3)归类案例6、批注7、备忘录链接1、查看nvivo版本 2、nvivo是如何支持质性研究的 是一个迭代的过…

MATLAB算法实战应用案例精讲-【数据分析】时许异常检测

前言 时间序列异常检测的目的就是在时间序列中寻找不符合常见规律的异常点,无论是在学术界还是工业界这都是一个非常重要的问题。企业的运维场景中有海量的运维指标数据,如果单纯依靠人力来发现并定位异常,将是十分低效的,所以如果可以开发一个智能运维系统对于异常波动自…

MAC地址

目录MAC地址广播信道的数据链路层必须使用地址&#xff08;MAC&#xff09;IEEE 802局域网的MAC地址格式IEEE 802局域网的MAC地址发送顺序单播MAC地址举例广播MAC地址举例多播MAC地址举例MAC地址 使用点对点信道的数据链路层不需要使用地址使用广播信道的数据链路层必须使用地址…

加解密与HTTPS(6)

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e;随着成本的下降&#xff0c;主流网站都已经开始使用HTTPS了。但有了可信机构颁发的证书&#xff0c;网站就真的绝对安全了吗&#xff1f;以之前出现过的上大学被冒…

多任务系统概述

一个例子&#xff1a; int Main(void) { TargetInit(); //初始化目标板OSInit(); //初始化操作系统 OSTaskCreate(Task0,&StackTask0[StackSizeTask0 - 1],PrioTask0); // 创建一个任务Uart_Printf("Ready to start OS\n"); OSStart(); //运行操作系统return 0…

AtCoder Beginner Contest 284(A~E)

比赛名称&#xff1a;AtCoder Beginner Contest 284 比赛链接&#xff1a;AtCoder Beginner Contest 284 A - Sequence of Strings 输入若干字符串&#xff0c;再把这些字符串按输入顺序倒序输出 #include <bits/stdc.h> using namespace std; signed main() {ios::sy…

年终盘点(二)丨2022计讯物联荣誉资质大盘点

峥嵘岁月&#xff0c;奋力前行。2022年&#xff0c;计讯物联积极发扬实干精神&#xff0c;聚力做强做精做专物联网产业&#xff0c;全面助力数字化转型升级&#xff0c;以硬核的实力揽获多项殊荣。 每一项荣誉的背后是计讯领导的的正确指导与全力支持&#xff0c;更是全体计讯人…