2017-02-01 3 views
-1

Учитывая таблицу продаж с количеством продаж, хранящимся в местной валюте и таблицу обменных курсов, содержащий коэффициент конверсии валюты, чтобы получить общий объем продаж в долларах США за каждый день продажи Мне нужен запросSQL запроса для выборки курса

Таблицы

продаж :

Sales Date Sales Amount Currency  
01-JAN-16   500 INR  
01-JAN-16   100 GBP  
02-JAN-16   1000 INR  
02-JAN-16   150 GBP  
03-JAN-16   1500 INR 

Таблица обменных курсов:

Source Currency Target Currency Exchange Rate Effective Start Date 
INR    USD      0.014 31-DEC-15  
INR    USD      0.015 02-JAN-16  
GBP    USD      1.32 20-DEC-15  
GBP    USD      1.30 01-JAN-16  
GBP    USD      1.35 10-JAN-16 

не имеют ни малейшего представления о том, как мне действовать

Я должен сделать две вещи совпадать с валютой, а затем проверить на ту же дату курса или до sales_date

ответ

0

Попробуйте это:

with SOURCE as 
(
select s1.*, coalesce(e1.Rate, 1) as ExRate, row_number() over(partition by e2.Source order by e2.StartDate desc) as r_num 
from Sales s1 
left join Exchange e2 
on s1.Currency = e2.Source 
and e2.StartDate <= s1.SalesDate 
) 
select SOURCE.*, SalesAmount*ExRate as USDAmount 
from SOURCE 
where r_num = 1 
+0

спасибо, я могу понять и его запуск –

0

давно Oracle представила аналитические функции для этого вида обработки - чтобы избежать объединения, что часто может быть дорогостоящим (требуется много времени для обработки, по сравнению со всем остальным в запросе).

В этом типе проблемы наиболее эффективны union all две таблицы, используя значения столбцов null, где необходимо; затем используйте функцию last_value, игнорируя нули, а затем просто собирайте результаты.

Предположения:

  1. таблица обменных курсов имеет коэффициент конверсии для различных целевых валют, а не только USD. Данные теста не иллюстрируют это, но в запросе я выбираю только строки, где target_currency = 'USD', чтобы это разрешить. (Действительно, если в таблице только обменные курсы для целевого = доллара, то целевой столбец валюты не понадобится).
  2. Курс обмена не может быть обнулен. (Не должно быть!)
  3. Для каждой даты транзакции для той же валюты есть строка в таблице обменных курсов с той же или более ранней эффективной датой начала. Это ограничение между таблицами, которое должно поддерживаться на уровне БД.

Запрос (в том числе тестовых данных в with пункте - не нужны при использовании базовых таблиц)

with 
    sales (sales_date, sales_amount, currency) as (  
     select to_date('01-JAN-16', 'dd-MON-rr'), 500, 'INR' from dual union all 
     select to_date('01-JAN-16', 'dd-MON-rr'), 100, 'GBP' from dual union all 
     select to_date('02-JAN-16', 'dd-MON-rr'), 1000, 'INR' from dual union all 
     select to_date('02-JAN-16', 'dd-MON-rr'), 150, 'GBP' from dual union all 
     select to_date('03-JAN-16', 'dd-MON-rr'), 1500, 'INR' from dual 
    ), 
    exch_rate (source_currency, target_currency, exchange_rate, effective_date) as (
     select 'INR', 'USD', 0.014, to_date('31-DEC-15', 'dd-MON-rr') from dual union all 
     select 'INR', 'USD', 0.015, to_date('02-JAN-16', 'dd-MON-rr') from dual union all 
     select 'GBP', 'USD', 1.32, to_date('20-DEC-15', 'dd-MON-rr') from dual union all 
     select 'GBP', 'USD', 1.30, to_date('01-JAN-16', 'dd-MON-rr') from dual union all 
     select 'GBP', 'USD', 1.35, to_date('10-JAN-16', 'dd-MON-rr') from dual 
    ), 
    prep (dt, amt, src_curr, x_rate) as (
     select sales_date, sales_amount, currency, null from sales 
     union all 
     select effective_date, null, source_currency, exchange_rate 
     from exch_rate 
     where target_currency = 'USD' 
    ), 
    with_x_rates (dt, amt, src_curr, x_rate) as (
     select dt, amt, src_curr, 
       last_value (x_rate ignore nulls) 
        over (partition by src_curr order by dt, x_rate) as x_rate 
     from prep 
    ) 
select dt as sales_date, amt as sales_amount, src_curr as currency, 
     x_rate as exchange_rate, 
     amt * x_rate as sales_amount_in_usd 
from  with_x_rates 
where amt is not null 
order by sales_date, currency -- if needed 
; 

Выходные:

SALES_DATE SALES_AMOUNT CURRENCY EXCHANGE_RATE SALES_AMOUNT_IN_USD 
---------- ------------ -------- ------------- ------------------- 
01-JAN-16   100 GBP    1.300    130.000 
01-JAN-16   500 INR    0.014    7.000 
02-JAN-16   150 GBP    1.300    195.000 
02-JAN-16   1000 INR    0.015    15.000 
03-JAN-16   1500 INR    0.015    22.500 

5 rows selected. 

Примечание: Выходной сигнал запроса имеет каждый столбец в соответствующем типе данных (дата, номер и т. д.). Форматирование было выполнено в SQL * Plus; мы не хотим форматировать данные (конвертировать их в строки) в SQL-запрос, поскольку, возможно, это не конечный продукт; его выход может потребляться дальнейшей обработкой.

Смежные вопросы