当前位置: 首页 > 科技观察

SQL中的self-join怎么理解?

时间:2023-03-14 20:21:57 科技观察

本文转载自微信公众号《SQL数据库开发》,作者,平凡的世界。转载本文请联系SQL数据库开发公众号。说起自连接,想必大家都有所耳闻。Self-join在数据处理中经常用到,特别是在一些连续性的问题中。什么是self-join,那么我们怎么理解self-join呢?说白了,自连接其实就是两张结构和数据内容完全一样的表。在做数据处理的时候,我们通常会通过重命名来区分他们(言外之意:不重命名是不行的,否则数据库不知道他们是谁),然后进行关联。我们来看看它们是如何进行自连接的。示例表的内容是下表Student。表结构和数据如下:我们进行自连接时,没有加过滤条件。具体如下:SELECTs1.SnameASSname1,s2.SnameASSname2FROMStudents2,Students1得到的结果如下:这个结果看着眼熟,好像在哪里见过。没错,其实就是我们的数学排列。大致安排是酱料:首先name1中的张三与name2中的张三、李四、王五组合形成前三条记录,然后name1中的李四与张三、李四、王五组合name2分别为李四。王舞组合形成了中间3条记录,最后name1中的王舞与name2中的张三、李四、王舞组合形成了后3条记录,所以我们得到了上面的结果。但是我们常见的大部分自连接其实都是有条件的。不管是什么条件,其实都是在上面的结果上筛选出来的。比如我们要查找一一对应的数据,我们可以这样写:SELECTs1.SnameASSname1,s2.SnameASSname2FROMStudents2,Students1WHEREs1.Sname=s2.Sname结果是两个自连接表一一对应-一:这里是self-join本质上是张三与自己的关联,那么你认为这是一种什么样的关联呢?但是在我们的工作中,使用自连接的目的并不是为了和自己关联,更多时候是为了和表中的其他人结合,像这样:SELECTs1.SnameASSname1,s2.SnameASSname2FROMStudents2,Students1WHEREs1.Sname<>s2.Sname的结果如下:另外,如果我们要进一步排除重复的数据行,比如张三,李四和李四,张三,我们默认这两行是重复数据(虽然顺序不同,但是在数学集合上,这两行可以看作是同一个结果集),如果只想保留一个,可以这样:SELECTs1.SnameASSname1,s2.SnameASSname2FROMStudents2,Students1WHEREs1.Sname>s2.Sname得到的结果是如下:这样,我们就得到了3行“不重复”的数据,这和数学组合是一样的。Self-join实战上面我们举了一个self-join来处理连续性问题。下面再举一个使用self-join删除重复数据的例子:例子表结构有如下Student表。表结构和数据如下:我们要删除表中重复的数据行,这个SQL怎么写?我们分析一下,发现这张表没有主键ID。为了区分它们,我需要给它添加一个虚拟主键。怎么做?可以这样写:SELECTIDENTITY(INT)ID,Sname,ScoreINTOStudent_TmpFROMStudent这里我们使用自增函数IDENTITY()生成一个类似于自增主键的ID,并将结果插入到Student_Tmp中,其中具体Student_Tmp中的内容如下:然后,我们可以通过保留最大值或最小值的方式删除重复项,如下:;这样我们就可以删除ID为3和4的列表了。查看Student_Tmp中的内容如下:注意:由于SQLServer的一些限制,我们无法对源表进行上述操作。为了演示自连接的作用,我们做了一定的调整。SQLServer中如果要删除原表中的重复行,可以使用以下方法:SELECTDISTINCT*INTOStudent_TmpFROMStudentTRUNCATETABLEStudentINSERTINTOStudentSELECT*FROMStudent_TmpDROPTABLEStudent_Tmp通过上述方法,我们使用自连接的方法删除Student_Tmp中的重复行。以上是自连接的一些主要用法,有不懂的地方请留言~