jpa多表关联查询_SQL基础第三讲:多表之间的关联查询

    在我久远的大学时代,当时应该是大三吧,在某家通信公司做实习生,就是给一个领导做资料,数据方面的资料,我们五个人给他一个人提供报表,我们呢,就是分不同方向,将十几个表格中的数据汇总起来,形成PPT然后给领导去开会使用。

    当时是碰到这样一个问题,就是在一个表格中匹配另外一个表格的数据,然后找到表格1 中有的 ,将表格2中的数据写在表格1 的最后一列,大概的数学模型是这样:

        表格1中的数据:

e57615f083b88ea0025e8c3483c20636.png

        表格2中的数据:

dc1ba5eddc26fd92423985890dd93e1b.png

        目的是希望得到这样的效果:

4e15e5f9205bf13f854193d777c69468.png

    当然,真实情况数据比这个要多的多,也更加的复杂,这里只是一个简单的数学模型,由于刚接触工作,对表格也不是很熟悉,自己研究了半天,各种复制,排序,但是就是得不到这样的结果,后来去请教了一位老员工,他给我说这样用VLPPKUP啊,当时说实话, 我连这几个字母都没听清楚,后来又请教了一下,自己也上网搜了一下资料,才将这个东西给做出来。虽然现在已经忘记具体怎么样操作,但是一直记得excel中有这个功能,直到后来工作使用数据库后,才发现,这个用关联做起来真的是无比简单。

    我们先创建表

create table t1 (sno int,sname char(100),course char(100));--创建学生选课表create table t2 (course char(100),tname char(100));--创建教师表

977bbb25e762c716689ef2c716594309.png

    可以看到表已经创建 ,然后我们插入数据

insert into t1(sno,sname,course) values (1001  ,'张三'      ,'语文' );insert into t1(sno,sname,course) values (1001  ,'张三'      ,'数学' );insert into t1(sno,sname,course) values (1001  ,'张三'      ,'英语' );insert into t1(sno,sname,course) values (1004  ,'李四'      ,'语文' );insert into t1(sno,sname,course) values (1005  ,'王二麻子'  ,'英语' );insert into t2(course,tname) values ('语文','张老师');insert into t2(course,tname) values ('数学','王老师');insert into t2(course,tname) values ('英语','孙老师');

41b654632ff9f103c27b0b27f32ff331.png                0d4994fb845d797262de8facd41cc8b7.png

    可以看到两张表都已经有数据,接下来我们进行一个叫做内关联的操作(inner join ):

select t1.sno,t1.sname,t1.course,t2.tname from t1 inner join t2 on t1.course=t2.course;

94432ec1925dd94d42e65bc18a1e3217.png

    可以看到已经得到我们想要的数据了,这个代码的前提是教师表中必须包含所有的课程,假如有一个学生选了一门还没有招到教师的课程,也就是教师表中不存在这个课程,那么,这个代码会执行出来怎样的结果呢?

    我们先在学生表中写入一个新学生 王五,选择了教师表中没有的化学课程,虽然我不喜欢化学。

insert into t1(sno,sname,course) values (1006 ,'王五'  ,'化学' );

bf00d1442e3dc5da72744a794ef0f890.png

    可以看到,王五已经被写入。接下来我们运行代码

59c09e7e5887d9f95a053fd7d0718d2e.png

    可以看到,王五这个学生消失了,因为在教师表中不存在化学,所以查询出来的结果没有被显示,这种只保留符合关联条件的数据,也就是 表1 的课程等于表2 课程的关联方式,我们叫做内关联。

    这时候,肯定就有人问了,有没有一种方法,可以保留学生表的所有数据,那肯定是有的,有内关联,自然就有外关联(outer join ),外关联分为左外关联和右外关联,根据你想要保留左边表的全部数据还是想要保留右边表的所有数据,可以进行适当的选择,当然,在工作中我们统一使用的是左外关联,保持代码的一致性。

select t1.sno,t1.sname,t1.course,t2.tname from t1 left join t2 on t1.course=t2.course;

       写代码时,通常会省略 outer。

2ad98d16351d8dbda5efecaae74db07f.png

    根据查询结果,可以看到我们的王同学又回来了,这时候,我们看到王五同学的化学老师名字为(NULL),这里的null代表的就是空,就是没有值得意思,显然,这样看着不是很明了。所以我们可以利用一个在数据库中非常常用的函数,空值转换函数 :ifnull(字段,转换后的值)  这个函数的作用就是将字段里面的空值转换为你所指定的值,可以是其他字段,也可以是常量。

select t1.sno,t1.sname,t1.course,ifnull(t2.tname ,'未找到老师')from t1 left join t2 on t1.course=t2.course;

0e56e722b3f27dcfea7c6189ab647c9e.png

       ps:这里的ifnull()只是MySQL的空值转换函数,在oracle是nvl(),在hana是isnull(),其他数据库都大同小异,所起的作用是一样的。

    还有一种极端的情况,就是某位教师教的课程很烂,以至于无人挑选,但是还是想把它显示在表格中以示存在,就是保留两边所有的数据,这时候就需要用到全外关联(full join) 

    先给教师表插入一个无人问津的教师;

insert into t2(course,tname) values ('法语','赵老师');

369641a79f27c5036b8dee2a8efebb88.png

可以看到,数据已经被插入,然后运行如下代码:

select t1.sno,t1.sname,t1.course,ifnull(t2.tname ,'未找到老师')from t1 FULL  JOIN  t2 on t1.course=t2.course;

    这里我使用的是MYSQL数据库,mysql是没有全外连接这个概念的,但是可以靠其他方法来实现。这个代码在oracle数据库中可以运行,大家可以自行实验,但是在工作中,这种情况非常少见,大部分时候用左外关联,因为关联通常是将事实表和维度表进行关联。

    有一点没有讲到,on后面的内容就是关联条件,也是两张表之间连接的桥梁。

    总结一下今天的内容:

    1.内关联:inner join :只保留符合关联条件的数据

    2.外关联:outer join :保留符合关联条件的数据和所选择的一侧全部数据

                                        其中全外关联属于外关联的一种

   3.空值转换函数: ifnull()  ,nvl() ,isnull() :可以将空值转换为特定的值

    刚开始编写文章,很多地方都有不足,希望以后可以为大家贡献出更好的文章,谢谢大家!

    ps:还没有讲解如何安装数据库软件,我会在公众号的菜单栏中添加了安装教程供大家安装,谢谢1386e10f81e25b30ba5d9a131d75e0ce.png1386e10f81e25b30ba5d9a131d75e0ce.png,碰到安装上的问题也可以给作者发消息或者留言~~

                    c9b36ff33c968b0d14815dc5b58d79ac.png  感觉还不错的话,点下在看鼓励一下作者吧  c9b36ff33c968b0d14815dc5b58d79ac.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值