基于双列关联取最新日期对应t2_type的SQL语句优化问询
嘿,这个场景我经常碰到,你的现有语句虽然能跑,但确实有可以优化的地方,而且还存在一个小隐患——最后那个WHERE t2_date = Last_Date会把t1里没有匹配t2记录的行给过滤掉,因为NULL和NULL比较在SQL里是不成立的,这就违背了你用LEFT JOIN想要保留所有t1数据的初衷啦。
下面给你几种更简洁高效的写法,还能完美保留LEFT JOIN的效果:
解决关联表获取最新日期对应字段的简洁方案
方法一:窗口函数(最推荐,现代数据库通用)
用ROW_NUMBER()窗口函数给每组(按company+t2_t1_id分组)的记录按日期倒序排名,直接取排名第一的那条就是最新日期的记录,逻辑清晰又高效:
SELECT t1.t1_id, t1.Company AS t1_some_field, t2_ranked.t2_type FROM t1 LEFT JOIN ( SELECT *, -- 按公司和关联的t1_id分组,日期倒序排,每组第一条rn=1 ROW_NUMBER() OVER (PARTITION BY company, t2_t1_id ORDER BY t2_date DESC) AS rn FROM t2 ) t2_ranked ON t1.Company = t2_ranked.company AND t1.t1_id = t2_ranked.t2_t1_id -- 保留排名第一的t2记录,或者没有匹配t2的t1记录(rn为NULL) WHERE t2_ranked.rn = 1 OR t2_ranked.rn IS NULL;
如果你的数据库支持QUALIFY子句(比如BigQuery、Snowflake、PostgreSQL 13+),还能把语句缩得更短,省去子查询:
SELECT t1.t1_id, t1.Company AS t1_some_field, t2.t2_type FROM t1 LEFT JOIN t2 ON t1.Company = t2.company AND t1.t1_id = t2.t2_t1_id -- 直接筛选每组最新的记录,或者无匹配的t1行 QUALIFY ROW_NUMBER() OVER (PARTITION BY t1.t1_id ORDER BY t2.t2_date DESC) = 1 OR t2.t2_t1_id IS NULL;
方法二:LATERAL JOIN(逻辑最直观)
如果你的数据库支持LATERAL JOIN(比如PostgreSQL、MySQL 8.0.14+),可以直接给每条t1记录匹配t2中最新的那条,写法非常直观:
SELECT t1.t1_id, t1.Company AS t1_some_field, t2_latest.t2_type FROM t1 LEFT JOIN LATERAL ( -- 找到当前t1记录对应的最新t2行 SELECT t2_type FROM t2 WHERE t2.company = t1.Company AND t2.t2_t1_id = t1.t1_id ORDER BY t2_date DESC LIMIT 1 ) t2_latest ON true;
这种写法就像给每条t1记录单独执行一次子查询找最新的t2数据,没有匹配的话就返回NULL,完全符合LEFT JOIN的需求。
方法三:关联子查询(兼容老版本数据库)
如果你的数据库比较老,不支持窗口函数或LATERAL JOIN,用关联子查询也能实现,就是稍微啰嗦一点:
SELECT t1.t1_id, t1.Company AS t1_some_field, t2.t2_type FROM t1 LEFT JOIN t2 ON t1.Company = t2.company AND t1.t1_id = t2.t2_t1_id -- 匹配最新日期的t2记录,或者无匹配的t1行 WHERE t2.t2_date = ( SELECT MAX(t2_date) FROM t2 t2_sub WHERE t2_sub.company = t1.Company AND t2_sub.t2_t1_id = t1.t1_id ) OR t2.t2_t1_id IS NULL;
内容的提问来源于stack exchange,提问作者sare3th
相关产品推荐
相关产品推荐

