Если в вашей таблице 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]
Наконец, во внешнем соединении мы сообщаем запросу объединить все даты между этими двумяценности.Однако, поскольку один набор имеет нулевую конечную дату, мы добавляем условие или, чтобы игнорировать верхнюю границу в этом случае.
Я начал изучать SQL с Litwin, et.al.95 Руководство разработчика "и много читаю Usenet, так что мои источники немного устарели ...