如何关联SGD汇率表与支付交易表,匹配对应及最近历史汇率?
问题:交易表关联汇率表获取最新可用汇率
表结构与数据
SGD汇率表(Table_1)
| CURRENCY | Date | RATE |
|---|---|---|
| USD | 1/1/2011 | 1.2651 |
| USD | 15/1/2011 | 1.2611 |
| USD | 29/1/2011 | 1.2605 |
| USD | 12/2/2011 | 1.2581 |
| USD | 26/2/2011 | 1.2603 |
| AUD | 1/1/2011 | 1.3144 |
| AUD | 15/1/2011 | 1.3133 |
| AUD | 29/1/2011 | 1.3188 |
| AUD | 12/2/2011 | 1.3164 |
| AUD | 26/2/2011 | 1.3195 |
支付交易表(Table_2)
| TRX DATE | CURRENCY | AMOUNT |
|---|---|---|
| 1/1/2011 | AUD | 100 |
| 9/1/2011 | USD | 300 |
| 17/1/2011 | AUD | 400 |
| 17/1/2011 | USD | 500 |
| 21/1/2011 | AUD | 600 |
| 25/1/2011 | USD | 800 |
| 3/2/2011 | USD | 900 |
| 8/2/2011 | AUD | 200 |
| 13/2/2011 | USD | 300 |
| 18/2/2011 | USD | 500 |
| 21/2/2011 | AUD | 600 |
| 5/3/2011 | AUD | 900 |
需求说明
将支付交易表关联到SGD汇率表,为每笔交易匹配对应货币的汇率:
- 若交易日期存在对应汇率,直接使用该汇率
- 若交易日期无对应汇率,使用该日期之前最新可用的汇率
预期结果
| TRX DATE | CURRENCY | AMOUNT | RATE |
|---|---|---|---|
| 1/1/2011 | AUD | 100 | 1.3144 |
| 9/1/2011 | USD | 300 | 1.2651 |
| 17/1/2011 | AUD | 400 | 1.3133 |
| 17/1/2011 | USD | 500 | 1.2611 |
| 21/1/2011 | AUD | 600 | 1.3133 |
| 25/1/2011 | USD | 800 | 1.2611 |
| 3/2/2011 | USD | 900 | 1.2605 |
| 8/2/2011 | AUD | 200 | 1.3188 |
| 13/2/2011 | USD | 300 | 1.2581 |
| 18/2/2011 | USD | 500 | 1.2581 |
| 21/2/2011 | AUD | 600 | 1.3164 |
| 5/3/2011 | AUD | 900 | 1.3195 |
尝试的错误SQL
用户尝试的SQL仅匹配日期完全相等的记录,导致非匹配日期的汇率为NULL:
select Table_2.TRX_DATE, Table_2.CURRENCY, Table_2.AMOUNT, rate from Table_2 left join Table_1 on Table_2.TRX_DATE >= Table_1.Tgl and Table_2.TRX_DATE <= Table_1.Tgl and Table_2.CURRENCY = Table_1.Currency
错误结果
| TRX DATE | CURRENCY | AMOUNT | RATE |
|---|---|---|---|
| 1/1/2011 | AUD | 100 | 1.3144 |
| 9/1/2011 | USD | 300 | NULL |
| 17/1/2011 | AUD | 400 | NULL |
| 17/1/2011 | USD | 500 | NULL |
| 21/1/2011 | AUD | 600 | NULL |
| 25/1/2011 | USD | 800 | NULL |
| 3/2/2011 | USD | 900 | NULL |
| 8/2/2011 | AUD | 200 | NULL |
| 13/2/2011 | USD | 300 | NULL |
| 18/2/2011 | USD | 500 | NULL |
| 21/2/2011 | AUD | 600 | NULL |
| 5/3/2011 | AUD | 900 | NULL |
正确SQL实现方案
方案一:关联子查询(通用型,适用于多数数据库)
通过子查询为每笔交易筛选同货币下、日期不晚于交易日期的最新汇率:
SELECT t2.TRX_DATE, t2.CURRENCY, t2.AMOUNT, ( SELECT TOP 1 t1.RATE FROM Table_1 t1 WHERE t1.CURRENCY = t2.CURRENCY AND t1.Date <= t2.TRX_DATE ORDER BY t1.Date DESC ) AS RATE FROM Table_2 t2;
注:若使用MySQL,需将
TOP 1替换为LIMIT 1;若使用PostgreSQL,同样用LIMIT 1。
方案二:窗口函数(适用于支持ROW_NUMBER()的数据库,如SQL Server、MySQL 8+、PostgreSQL等)
先关联符合日期条件的汇率记录,再通过窗口函数筛选每组的最新汇率:
WITH RankedRates AS ( SELECT t2.TRX_DATE, t2.CURRENCY, t2.AMOUNT, t1.RATE, ROW_NUMBER() OVER ( PARTITION BY t2.TRX_DATE, t2.CURRENCY ORDER BY t1.Date DESC ) AS rn FROM Table_2 t2 LEFT JOIN Table_1 t1 ON t1.CURRENCY = t2.CURRENCY AND t1.Date <= t2.TRX_DATE ) SELECT TRX_DATE, CURRENCY, AMOUNT, RATE FROM RankedRates WHERE rn = 1;
内容的提问来源于stack exchange,提问作者adrione
相关产品推荐
相关产品推荐

