LEFTJOIN查询表中最新记录案例小记

科技一点鑫得 2024-03-07 13:40:39

需求

有一张按照时间顺序记录的表demo,name是允许重复的,希望从表中查询出所有不重复name最新的那一条记录,以下图中的记录为例期望查询出的结果为id为1、4、5的记录,分别对应A、B、C的最新记录。在真实场景中,按照时间查询出最新的不重复记录也是很常见的诉求,本文将以这个简化的demo表介绍如何实现这个查询。

查询SQL

这里先给出答案,使用下面的sql语句就可以查询出想要的结果,可见下图中查询的结果和上面的预期一致。乍一看下面的sql并不好理解,接下来我们逐步拆解这条sql,看看是如何一步步得到答案的。

SELECT t1.* from demo t1 LEFT JOIN demo t2 ON t1.name=t2.name AND t1.created<t2.created WHERE t2.name IS NULL;

步骤拆解

首先,执行简单的LEFT JOIN看看能得到什么,LEFT JOIN用于连接表,它会从左表返回所有的行,即使右表没有匹配的行。下面的sql使用LEFT JOIN连接了两张表,只不过这张表是一样的,t1和t2是为表demo取的别名,连接的条件是两张表的name相同,ON类似于where。

SELECT * from demo t1 LEFT JOIN demo t2 ON t1.name=t2.name;

为什么得到的是9条记录呢?这里可以看作是两层嵌套循环,第一次遍历demo的5条记录,其中的每一条记录又遍历一次demo找到name相同的则添加一条记录,这样最终就会得到9条记录。

接下来增加一个条件,t1.created<t2.created,这次也同样是两层嵌套,只是在循环遍历时不仅要name相同,还要求第一层的created较早。以id为1的A记录为例,它本身就是最新的记录,因此找不到与它匹配的记录,LEFT JOIN的特性要求它也必须生成一条记录,只是t2的字段全部为NULL。

SELECT * from demo t1 LEFT JOIN demo t2 ON t1.name=t2.name AND t1.created<t2.created;

从上面的查询结果可知所有左表t1的最新记录都无法找到匹配的右表记录,因此右表t2的字段全部都为NULL,这时候是不是该意识到什么了?我们只要在这个结果中查询出t2为NULL的记录就是想要的结果了。

SELECT * from demo t1 LEFT JOIN demo t2 ON t1.name=t2.name AND t1.created<t2.created WHERE t2.name IS NULL;

上面的结果t2的字段全部为null,显然不需要,况且t1和t2本身也是相同的表,再次调整一下sql就可以得到最终的查询语句了。

SELECT t1.* from demo t1 LEFT JOIN demo t2 ON t1.name=t2.name AND t1.created<t2.created WHERE t2.name IS NULL;
0 阅读:0

科技一点鑫得

简介:感谢大家的关注