Как конвертировать из одной валюты в другую в запросе Oracle - PullRequest
0 голосов
/ 14 января 2020

Я выбираю дочерние расходы в долларах США на конкретную дату. Но мне нужно конвертировать его в выигранную валюту на эту дату. Стоимость валюты меняется в любое время в зависимости от доллара США. История валют находится в таблице V_CURRENCY . Мне нужно умножить доллар на эту сумму и показать в выигрыше. Мой запрос ниже и дает ошибку. Ошибка [22008] [1861] ORA-01861 . Несоответствие строк.

with cte as (
    select t.filial_code,
           t.modified_by                      as emp_code,
           sum(t.sum_oper)                    as summa,
           to_char(t.oper_date, 'YYYY-MM-DD') as operation_date
    from OPERS t,
         DEP_OPERS d
    WHERE 
      And t.modified_by = 213
      And t.filial_code = '00116'
      And d.currency_code = 840
      And t.oper_date >= to_date('07.01.2020', 'DD.MM.YYYY')
      And t.oper_date < to_date('11.01.2020', 'DD.MM.YYYY')
    group by to_char(t.oper_date, 'YYYY-MM-DD'), t.filial_code, t.modified_by
) select cte.filial_code,cte.emp_code,cte.summa * (select equival from V_CURRENCY
    where date_activ = (select max(date_activ)
                            from V_CURRENCY
                         where date_activ <= cte.operation_date) and code = 840) as summa,cte.operation_date from cte;

Из cte я беру следующий результат:

FILIAL_CODE | EMP_CODE | SUMMA | OPERATION_DATE
-----------------------------------------------
00116       | 213      | 40000 | 2020-01-14
00116       | 213      | 6000  | 2020-01-10
00116       | 213      | 2800  | 2020-01-06

Моя V_CURRENCY таблица похожа на приведенную ниже:

CODE   | DATE_ACTIV             | EQUIVAL|
--------------------------------
840    | 2020-01-13 00:00:00    | 576.97
840    | 2020-01-07 00:00:00    | 2008.54
840    | 2020-01-06 00:00:00    | 1941.91
840    | 2019-12-22 00:00:00    | 301.62
190    | 2020-01-13 00:00:00    | 1200.97
270    | 2020-01-13 00:00:00    | 2300.21
800    | 2019-12-22 00:00:00    | 100.62

Мне нужно умножить эквивалент из таблицы V_CURRENCY в дате 2020-01-13 00: 00: 00 на мой результат CUM SUMMA для OPERATION_DATE 2020-01-14 , означает, что 4000 * 576.97, причина OPERATION_DATE является наиболее близкой к дате изменения валюты. Но если для даты 2020-01-06 существует DATE_ACTIV , то 2800 * 1941.91. Мне нужно только значение валюты, чей код 840.

Мой последний результат должен выглядеть следующим образом:

FILIAL_CODE | EMP_CODE | SUMMA           | OPERATION_DATE
-----------------------------------------------
00116       | 213      | 40000 * 576.97  | 2020-01-14
00116       | 213      | 6000 *  2008.54 | 2020-01-10
00116       | 213      | 2800  * 1941.91 | 2020-01-06

Любой ответ приветствуется. Заранее спасибо.

1 Ответ

2 голосов
/ 14 января 2020

Используйте функцию LEAD analyti c, чтобы найти дату, до которой действительна конвертация валюты, и затем присоединитесь к таблицам в диапазоне между датами начала и окончания, в которых валюта действительна:

SELECT y.filial_code,
       y.emp_code,
       y.summa * c.equival AS summa,
       y.operation_date
FROM   your_cte y
       INNER JOIN (
         SELECT c.*,
                LEAD( DATE_ACTIV, 1, SYSDATE )
                  OVER ( PARTITION BY code ORDER BY date_activ )
                  AS DATE_FINISHED
         FROM   v_currency c
         WHERE  currency_code = 840
       ) c
       ON (   y.operation_date >= c.date_activ
          AND y.operation_date <  c.date_finished )

Выходы:

FILIAL_CODE | EMP_CODE |    SUMMA | OPERATION_DATE
:---------- | -------: | -------: | :-------------
00116       |      213 | 23078800 | 14-JAN-20     
00116       |      213 | 12051240 | 10-JAN-20     
00116       |      213 |  5437348 | 06-JAN-20     

дБ <> скрипка здесь

Как и в стороне, ваш CTE не не нужно преобразовывать даты в строки и использовать литералы даты и современное соединение ANSI (а не устаревшее соединение через запятую):

with cte ( filial_code, emp_code, summa, operation_date ) as (
    SELECT t.filial_code,
           t.modified_by,
           sum(t.sum_oper),
           t.oper_date
    from   OPERS t
           CROSS JOIN
           DEP_OPERS d
    WHERE  t.modified_by   = 213
    AND    t.filial_code   = '00116'
    AND    d.currency_code = 840
    AND    t.oper_date     >= DATE '2020-01-07'
    AND    t.oper_date     <  DATE '2020-01-11'
    GROUP BY t.oper_date,
             t.filial_code,
             t.modified_by
)
...

и вам даже не нужен CTE:

SELECT t.filial_code,
       t.modified_by               AS emp_code,
       SUM(t.sum_oper * c.equival) AS summa,
       t.oper_date                 AS operation_date
FROM   OPERS t
       CROSS JOIN
       DEP_OPERS d
       INNER JOIN (
         SELECT c.*,
                LEAD( DATE_ACTIV, 1, SYSDATE )
                  OVER ( PARTITION BY code ORDER BY date_activ )
                  AS DATE_FINISHED
         FROM   v_currency c
       ) c
       ON (   t.oper_date     >= c.date_activ
          AND t.oper_date     <  c.date_finished
          AND d.currency_code = c.currency_code )
WHERE  t.modified_by   = 213
AND    t.filial_code   = '00116'
AND    d.currency_code = 840
AND    t.oper_date     >= DATE '2020-01-07'
AND    t.oper_date     <  DATE '2020-01-11'
GROUP BY t.oper_date,
         t.filial_code,
         t.modified_by
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...