distinct sql用法_SQL进阶之自连接与外连接

本文探讨了《SQL进阶》中关于自连接和外连接的巧妙应用,通过实例解析如何利用这两种连接方法解决SQL面试难题。自连接用于查找局部不一致的列和排序,如成绩相同但课程不同的学生信息;外连接则适用于排序、求差集和购物篮分析,例如查询学过特定课程但未学过另一课程的学生。此外,还介绍了自连接在外连接中进行时间比较的应用,如对比年销售额和寻找最近年份的数据。
摘要由CSDN通过智能技术生成

《SQL进阶》这本书里提到了自连接和外连接的一些用法,在处理一些问题上显得特别简单,思路很巧妙。学习书上的例子,我把之前做过的SQL经典面试50题的有些题就可以很好运用作者提到的思路。

一、自连接的用法

1、查找局部不一致的列

- 41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

解题思路:这里要求的是成绩相同,但是课程不同的学生的信息,满足要求

代码关键的是自连接的条件(成绩相同,课程编号不同)

579a0d78196e97e3861615b1a96c5656.png

2、利用非等值自连接进行排序

自从mysql 8.0有了开窗函数,所以可以使用排序函数来进行排序。 但是作者给出了可以使用自连接的方法进行排序,思路很好,所以对于50题里部分排序题我也使用自连接方法进行排序。

- 20、查询学生的总成绩并进行排名

b9be201c2db742331866969bf9805c9c.png

进一步还能够进行分组排名

-- -- 19、按各科成绩进行排序,并显示排名

e0b37882815d3c2a8a98437fb9fdf261.png

作者这里使用自连接的进行排序的思路大致如下:以20题为例

04b6976e0756a572722c6add5e429f49.png

(应该再count()后加1,但是由于j键盘出了问题这里只能显示位次,若还想要显示不跳过排名可以使用count(distinct)

二、外连接的用法

1 、使用外连接排序

除了使用自连接还可以使用外连接来进行排序,其思路与自连接稍微有些不一样,但是总的来说还是一致的

-- 20、查询学生的总成绩并进行排名

a6e1210f82a6fc78ab93133e4deaf2fb.png

进一步的也可以进行分组排名

-- -- 19、按各科成绩进行排序,并显示排名

fa325ec4341a617955e8f4c7ae95fea1.png

利用外连接的思路具体如下:

ca419ba7585cfad30721c0d0472e8cf0.png

2 、使用外连接求差集

-- 10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息

解题思路:

可以将学过01课程的学生作为表1 ,学过02课程的学生作为表2,将两张表进行外连接,求出 表1与表2 的差集即可

6bd80d613a49b4824bdef7b31d472e2b.png

外连接求差集的逻辑为

da62cef997d8f33822b267513d3fb617.png

反过来如果学过02课程但是没有学过01课程的学生信息的代码为

d3b1f62bafe496ddb67b77aa636ecb6e.png

结果为

b7251710b3cbe37d2f43d39ac59f188b.png

3、使用外连接进行购物篮分析

这里的购物篮分析的原型是找出那些商品是经常一起购买而演变而来

举例如下图

fce7d6e5eb6ec9164b51c9c0dade1f18.png

具体代码

ae234222db84feba48a7fc7469daeeb9.png

06727c1741029dfe3e7cb32d76df1096.png

1c677ab4591d8c7ab0e07887cea1b030.png

这个形式可以运用很多场景,比如面试经典题中的

-- 13、查询和"01"号的同学学习的课程完全相同的其他同学的信息

解题思路:即将01同学所学课程作为一个临时表,与学生成绩表进行比对,此时的临时表上当于上图的表1,学生成绩表相当于上图的表2 .查询与01同学所学课程的数量一致,并且科目也一样。

因为where的条件限制只对某行数据有效,in则只要满足限制范围之一的即可,比如面试题的(-- 12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息)能够满足需求的则是having 语句

具体代码

e700490cdf716c4d1ffac747f2f90188.png

50a704c80e89948dfd42862c13cbc4eb.png

购物篮分析问题的一般化,若想要没有备齐全部商品类型的店铺,也可以返回这些店铺缺少多少种类的商品

使用外连接的代码

67a8a3a92a9e016882b644914e0323d0.png

使用自连接的代码

16bb0d5a1447f24b8bb0614df8b7dba9.png

结果为

f2719336a8e5584d5b3705653d653ce0.png

四、使用自连接进行时间比较

1、与上一年相比

解题思路:使用自连接创建两个表,销售额保持不变,年份偏移一年

因而关键是s2.year=s1.year-1这样一来s1的数据为今年的数据,s2的则为去年数据

8f20cef0b812ab13c74904022f10598d.png

具体结果

7e97dd5d854b702681b8ad091c1ac19d.png

2、与最近年份相比

关键是年份相近满足两个条件

7266ed202c6776d94145666d0684e9ab.png

具体代码以及结果

32f758ddc4fa1495541aa65e61965b1d.png

cbc185ee13868421dbcb075cd8a39812.png

如果想要把最早的年份也包含进来(比如1990)则可以使用自外连接,具体的代码与结果如下

c46e977269c43a6c927642d2b3d609c5.png

958e9e1d9f0c55b1ffa98bea6aa38e2a.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值