查询以获取与上一个生效日期对应的值

时间:2015-07-04 21:23:42

标签: sql sql-server sql-server-2014

我正在使用SQL Server 2014.我的数据库中有3个表需要在查询中加入,它们如下所示:

ResStayDate.dbo

ResaID    StayDate        Rate   
 50       2015-01-20      235.00
 50       2015-01-21      235.00
 50       2015-01-22      235.00
 50       2015-01-23      235.00
 54       2015-02-10      200.00
 54       2015-02-11      200.00
 65       2015-03-12      155.00
 65       2015-03-13      155.00
 67       2015-04-10      290.00
 67       2015-04-11      290.00
 67       2015-04-12      290.00

ResStay.dbo

 ResaID    Currency
  50        USD
  54        USD
  65        EUR
  67        EUR

ExchangeRate.dbo

Currency     ExRate     EffectiveDate
  USD        28.00       2015-01-20
  EUR        40.00       2015-01-20
  USD        30.00       2015-01-22
  EUR        40.00       2015-01-22
  USD        30.00       2015-03-13
  EUR        40.00       2015-03-13
  USD        30.00       2015-04-11
  EUR        42.00       2015-04-11

我希望我的查询提供的输出如下:

 ResaID       StayDate    Rate      ExRate        Revenue 
   50       2015-01-20   235.00     28.00          6580.00
   50       2015-01-21   235.00     28.00          6580.00
   50       2015-01-22   235.00     30.00          7050.00
   50       2015-01-23   235.00     30.00          7050.00
   54       2015-02-10   200.00     30.00          6000.00
   54       2015-02-11   200.00     30.00          6000.00
   65       2015-03-12   155.00     40.00          6200.00
   65       2015-03-13   155.00     40.00          6200.00
   67       2015-04-10   290.00     40.00         11600.00
   67       2015-04-11   290.00     42.00         12180.00
   67       2015-04-12   290.00     42.00         12180.00 

收入的计算方法如下:ResStayDate.Rate * ExRate(将Currency中的ResStay.dboCurrency中的ExchangeRate.dbo值进行匹配。

我的查询已取得了很大进展,但我仍然坚持如何将ResStayDate.StayDateExchangeRate.EffectiveDate匹配,以便查询可以使用{ExRate Currency 1}}。 我的问题在于ExchangeRate表不会每天列出货币的值,而只会在ExRate的{​​{1}}发生变化时才会列出。

因此,Currency的{​​{1}}在下次更改之前有效,依此类推。我需要将ExRate表格中的CurrencyStayDate表格中ResStayDate的相应ExRate值相匹配。

所以,我现在的草稿查询如下:

Currency

我无法弄清楚如何在查询中插入ExchangeRate,以便我可以使用公式来获取 SELECT * FROM ( (SELECT ResaID, StayDate, Rate, (?????) As [Revenue] FROM ResStayDate)a LEFT JOIN ResStay b ON b.ResaID = a.ResaID LEFT JOIN ExRate c ON c.Currency = b.Currency )xy 列。

2 个答案:

答案 0 :(得分:2)

我会在这里使用CROSS APPLY。 这是SQL Fiddle

ExchangeRate上为(Currency, EffectiveDate)添加索引,效果很好。

请确保ExchangeRate中第一个日期之前EffectiveDate的每种货币的ResStayDate值为CROSS APPLY,否则这些日期将不会在OUTER APPLY中获得任何匹配的行并且它们不会出现在最终结果中。如果您的数据可能包含不具有汇率的历史值,请使用CROSS APPLY代替SELECT ResStayDate.ResaID ,ResStayDate.StayDate ,ResStayDate.Rate ,CA.ExRate ,ResStayDate.Rate * CA.ExRate AS Revenue FROM ResStayDate INNER JOIN ResStay ON ResStay.ResaID = ResStayDate.ResaID CROSS APPLY ( SELECT TOP(1) ExchangeRate.ExRate FROM ExchangeRate WHERE ExchangeRate.Currency = ResStay.Currency AND ExchangeRate.EffectiveDate <= ResStayDate.StayDate ORDER BY ExchangeRate.EffectiveDate DESC ) AS CA ORDER BY ResaID, StayDate; 。在这种情况下,您将获得NULL,并且您至少会看到某些内容出错,而不是默默地在结果中没有行。

date1.toString().equals(date2.toString())

答案 1 :(得分:0)

为什么你不能在下面这样做,也使用ISNULL()功能

SELECT a.ResaID, 
        a.StayDate,
        a.Rate,
        a.Rate * ISNULL(c.ExRate,0) As [Revenue]
 FROM ResStayDate a
LEFT JOIN ResStay b ON b.ResaID = a.ResaID
LEFT JOIN ExchangeRate  c ON c.Currency = b.Currency;