如何在SQL中选取最近的前置匹配值?附Table1示例数据
嘿,这个需求我之前在项目里碰过好多次,其实有几种靠谱的SQL实现方式,我分情况给你拆解下,适配不同的数据库环境~
方案1:窗口函数(首推,适配主流新数据库)
如果你的数据库支持窗口函数(比如PostgreSQL、MySQL 8.0+、SQL Server、Oracle),这绝对是最简洁高效的选择。
举个例子,假设你有一张业务表Table2,里面存着需要匹配汇率的业务日期biz_date,我们可以通过关联+窗口函数精准找到每个业务日期对应的最近前置汇率:
WITH ranked_rates AS ( SELECT t2.biz_date, t1.日期 AS rate_date, t1.汇率, -- 按业务日期分组,把前置的汇率日期倒序排,取第一个就是最近的 ROW_NUMBER() OVER (PARTITION BY t2.biz_date ORDER BY t1.日期 DESC) AS rn FROM Table2 t2 LEFT JOIN Table1 t1 ON t1.日期 <= t2.biz_date ) SELECT biz_date, rate_date, 汇率 FROM ranked_rates WHERE rn = 1;
要是你只是想单独查某个特定日期的最近前置汇率,那代码可以更简单:
SELECT 汇率 FROM Table1 WHERE 日期 <= '2018-04-03' -- 换成你要查的目标日期 ORDER BY 日期 DESC LIMIT 1;
方案2:子查询(兼容老版本数据库)
如果你的数据库比较老(比如MySQL 5.x这类不支持窗口函数的),用子查询也能搞定。逻辑是先给每个目标日期找到Table1里小于等于它的最大日期,再通过这个日期关联取汇率:
SELECT t2.biz_date, t1.汇率 FROM Table2 t2 LEFT JOIN Table1 t1 ON t1.日期 = ( SELECT MAX(日期) FROM Table1 WHERE 日期 <= t2.biz_date );
方案3:LATERAL JOIN(适配PostgreSQL、SQL Server等)
对于支持LATERAL JOIN的数据库,这种写法可读性特别好,性能也不赖:
SELECT t2.biz_date, t1.汇率 FROM Table2 t2 LEFT JOIN LATERAL ( -- 对每个业务日期,查最近的前置汇率 SELECT 汇率 FROM Table1 WHERE 日期 <= t2.biz_date ORDER BY 日期 DESC LIMIT 1 ) t1 ON TRUE;
几个关键注意事项
- 一定要确保
日期字段是日期类型(比如DATE、DATETIME),别存成字符串!如果已经是字符串了,得先转成日期格式,比如MySQL用STR_TO_DATE(日期, '%m/%d/%Y'),Oracle用TO_DATE(日期, 'MM/DD/YYYY'),否则排序和比较会出错。 - 如果Table1里有重复的日期记录,得根据你的实际需求调整,比如用
RANK()代替ROW_NUMBER(),或者加额外条件去重。 - 大数据量的表记得给
日期字段建索引,能大幅提升查询速度!
内容的提问来源于stack exchange,提问作者Evie
相关产品推荐
相关产品推荐

