鉴于以当地货币存储销售额的销售表和包含货币转换率的汇率表,为了获得每个销售日期的总销售额,我需要查询
销售表:
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 :(得分: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
答案 1 :(得分:0)
很久以前,Oracle为这种处理引入了分析函数 - 避免加入,这通常很昂贵(与查询中的其他内容相比,需要花费很长时间才能处理)。
在这类问题中,union all
这两个表最有效,在需要时使用null
列值;然后使用last_value
函数,忽略空值,然后只收集结果。
<强>假设强>:
target_currency = 'USD'
允许的行。 (实际上,如果该表只有目标=美元的汇率,那么就不需要目标货币栏。) 查询(包括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查询中格式化数据(将其转换为字符串),因为这可能不是最终产品;其输出可能会被进一步处理所消耗。