我有两个像下面这样的表。我需要找到购买日期有效的汇率。我尝试了一些相关子查询,但我很难在子查询中使用相关记录。
我希望解决方案需要遵循以下基本轮廓:
- 仅选择适用国家/地区代码的汇率
- 从 1. 选择小于购买日期的最新汇率
- 使用 2. 中的所有字段和purchasingTable 填写查询表。
我的 table :
购买表:
> dateOfPurchase | costOfPurchase | countryOfPurchase
> 29-March-2010 | 20.00 | EUR
> 29-March-2010 | 3000 | JPN
> 30-March-2010 | 50.00 | EUR
> 30-March-2010 | 3000 | JPN
> 30-March-2010 | 2000 | JPN
> 31-March-2010 | 100.00 | EUR
> 31-March-2010 | 125.00 | EUR
> 31-March-2010 | 2000 | JPN
> 31-March-2010 | 2400 | JPN
购买成本以给定国家/地区代码的本地货币表示
<小时/>汇率表
> effectiveDate | countryCode | exchangeRate
> 29-March-2010 | JPN | 90
> 29-March-2010 | EUR | 1.75
> 30-March-2010 | JPN | 92
> 31-March-2010 | JPN | 91
<小时/>
我正在查找的查询结果:
> dateOfPurchase | costOfPurchase | countryOfPurchase | exchangeRate
> 29-March-2010 | 20.00 | EUR | 1.75
> 29-March-2010 | 3000 | JPN | 90
> 30-March-2010 | 50.00 | EUR | 1.75
> 30-March-2010 | 3000 | JPN | 92
> 30-March-2010 | 2000 | JPN | 92
> 31-March-2010 | 100.00 | EUR | 1.75
> 31-March-2010 | 125.00 | EUR | 1.75
> 31-March-2010 | 2000 | JPN | 91
> 31-March-2010 | 2400 | JPN | 91
例如,在结果中,3 月 31 日欧元的实际汇率为 1.75。
我使用的是 Access,但 MySQL 答案也可以。
更新:
修改艾伦的答案:
SELECT dateOfPurchase, costOfPurchase, countryOfPurchase, exchangeRate
FROM purchasesTable p
LEFT OUTER JOIN
(SELECT e1.exchangeRate, e1.countryCode, e1.effectiveDate, min(e2.effectiveDate) AS enddate
FROM exchangeRateTable e1
LEFT OUTER JOIN
exchangeRateTable e2
ON e1.effectiveDate < e2.effectiveDate AND e1.countryCode = e2.countryCode
GROUP BY e1.exchangeRate, e1.countryCode, e1.effectiveDate) e
ON p.dateOfPurchase >= e.effectiveDate AND (p.dateOfPurchase < e.enddate OR e.enddate is null) AND p.countryOfPurchase = e.countryCode
我必须做一些小改变。
最佳答案
如果您的 ExchangeRate 表没有任何间隙,这非常简单:
select dateOfPurchase, costOfPurchase, countryOfPurchase, exchangeRate
from purchasesTable p
inner join
exchangeRateTable e
on p.dateofpurchase = e.effectivedate
and p.countryofpurchase = e.countrycode
如果它确实有间隙(有效汇率设置为 1/1,直到 1/3 才改变,因此 1/1 汇率适用于 1/2),那么它会变得有点复杂,因为结束日期仅是暗示的。在这种情况下,以下内容应该有效:
select dateOfPurchase, costOfPurchase, countryOfPurchase, exchangeRate
from purchasesTable p
left outer join
(select e1.exchangeRate, e1.countrycode,
e1.effectivedate, min(e2.effectivedate) as enddate
from exchangeRateTable e1
left outer join
exchangeRateTable e2
on e1.effective_date < e2.effective_date
and e1.countrycode = e2.countrycode
group by e1.exchangeRate, e1.countrycode,
e1.effectivedate) e
on p.dateofpurchase >= e.effectivedate
and (p.dateofpurchase < e.enddate
or e.enddate is null)
and p.countryofpurchase = e.countrycode
如果您需要使用此解决方案,您可能希望将最里面的查询放入存储的查询中,既可以简化此操作,又可以使结束日期可供其他进程使用。
<小时/>我们正在做的是从汇率表 (e1
) 中获取每条记录,并将其连接到同一表 (e2
) 中的所有条目)稍后发生。我们取第二组值中的最小值 (min(e2. effectivedate)
)。
假设您只有三个值:
1/1/2000
1/3/2000
1/5/2000
连接将为您提供以下结果(每个值与所有更大的值相结合):
1/1/2000 < 1/3/2000
1/1/2000 < 1/5/2000
1/3/2000 < 1/5/2000
1/5/2000 < [null]
由于没有值小于 1/5/2000 并且我们指定了外部联接,因此第二个表的该行将具有空值。然后我们指定只需要第二个表中的最小值,因此结果集减少为:
1/1/2000 < 1/3/2000
1/3/2000 < 1/5/2000
1/5/2000 < [null]
最后,在最外层联接中,我们告诉查询联接这两个值之间的所有日期。但是,由于一组的结束日期为空,因此我们添加一个 or 条件来忽略这种情况下的上限。
<小时/>我从 Litwin 等人的“Access 95 开发人员手册”开始学习 SQL,并大量阅读 Usenet,所以我的资料有点过时了...
关于sql - 来自多个表的关联 SQL 连接查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2547671/