sql - 来自多个表的关联 SQL 连接查询

标签 sql mysql ms-access

我有两个像下面这样的表。我需要找到购买日期有效的汇率。我尝试了一些相关子查询,但我很难在子查询中使用相关记录。

我希望解决方案需要遵循以下基本轮廓:

  1. 仅选择适用国家/地区代码的汇率
  2. 从 1. 选择小于购买日期的最新汇率
  3. 使用 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/

相关文章:

php - 在定制论坛上获取热门话题

mysql - 如何使用 CASE 语句在 MySQL 中进行计数

mysql - SQLZOO - 从世界教程 #13 中选择

arrays - 如何将数组传递给VBA中的函数?

sql - 如何在ms access中使用distinct

sql - postgres 选择聚合时间跨度

sql - 下一个值函数错误

php - 填充空提交结果 mysql php

PHP AJAX 和 mySQL 不返回数据?

ms-access - 查找给定日期范围内的工作日/周末数