У меня есть таблица счетов-фактур, которые могут быть в нескольких валютах, которая выглядит следующим образом:
| id | issue_date | total | currency |
|----|------------|-------|----------|
| 1 | 2020-04-20 | 1234 | EUR |
| 2 | 2020-04-26 | 2345 | USD |
| 1 | 2020-04-27 | 9876 | EUR |
| 3 | 2020-04-28 | 3456 | RON |
И у меня есть таблица валют с курсами обмена, которая выглядит следующим образом:
| id | date | currency_id | rate |
|----|------------|-------------|---------|
| 1 | 2020-04-20 | EUR | 1 |
| 2 | 2020-04-20 | USD | 1.08600 |
| 3 | 2020-04-20 | RON | 4.83560 |
Я бы хотел рассчитать цену каждого счета на основе его issue_date
, currency
и целевой валюты.
Все курсы обмена валют основаны на евро, поэтому его стоимость всегда будет быть 1. Валюты обновляются ежедневно, но отсутствуют даты (в выходные дни обменные курсы не обновляются), поэтому расчет должен быть основан на самом последнем обменном курсе до invoice.issue_date
Итак, я попробовал следующее:
SELECT
`i`.`id`,
`i`.`total`,
`i`.`currency`,
`exr1`.`rate` as `invoice_rate`,
`exr2`.`rate` AS `target_rate`,
`i`.`total` * `exr1`.`rate` as `euro_price`,
`i`.`total` * `exr1`.`rate` / `exr2`.`rate` AS `target_price`
FROM `invoices` as `i`
LEFT JOIN `exchange_rates` AS `exr1`
ON
`exr1`.`currency_id` = `i`.`currency` AND
`exr1`.`date` = `i`.`issue_date`
LEFT JOIN `exchange_rates` as `exr2`
ON
`exr2`.`currency_id` = 'RON' AND
`exr2`.`date` = `i`.`issue_date`
GROUP BY
`i`.`id`,
`invoice_rate`,
`target_rate`
ORDER BY `i`.`issue_date` DESC
Проблема № 1
Из-за отсутствия ставок обмена на точные даты выставления счетов я получаю значения null
. Я попытался изменить LEFT JOIN ON на что-то вроде exr1.date <= i.issue_date
, но счет GROUP BY больше не работает (я получаю дубликаты).
Проблема № 2
Для строк с курсами обмена в тот же день я получаю неправильные значения, потому что в зависимости от целевой валюты мне нужно либо умножить, либо разделить: i.total * exr1.rate * exr2.rate AS usd_price
vs i.total * exr1.rate / exr2.rate AS usd_price
https://www.db-fiddle.com/f/e5GnVnry5sAiXwbuScV6JT/19