繁体   English   中英

从汇率表隐式计算SQL中的汇率

[英]Implicitly Calculate Exchange Rates in SQL from Exchange Rate table

我有一个数据表,其中的收入以多种货币表示(我们称其为TRANSACTION_TABLE ,其列如下:

TRANSACTION_NAME
TRANSACTION_VALUE
CURRENCY

,以及另一个带有汇率( EXCHANGE_RATE )的表,其列如下:

FROM_CURRENCY (e.g. JPY)
TO_CURRENCY (e.g. USD)
EXCHANGE_RATE (x)

该表至少具有将每种货币转换为USD的功能,但对于非USD TO_CURRENCY值的汇率并没有穷尽TO_CURRENCY

我要实现的查询是一种将交易转换为任何货币的方法,即使未在EXCHANGE_RATE表中明确规定,也可以先将货币转换为USD,然后再从USD转换为目标货币。

例如1000 JPY为GBP:

  1. 查找日元对美元的汇率-计算= 1000 * EXCHANGE_RATE = 9
  2. 查找汇率GBP转换为USD-计算= 9 \\ EXCHANGE_RATE = 7

目前,我已经在EXCHANGE_RATE上为TRANSACTION_TABLE进行了左TRANSACTION_TABLE ,但是我迷失了下一步。

任何帮助将不胜感激。

到目前为止,我已经建立的查询(非常基本)如下,并且我是SQL的新手。 我首先构建此查询以将其转换为美元,但效果很好(因为我的汇率表包含所有货币的美元值),但是当将目标货币设置为GBP时,它显然会失败,因为它只会返回空值。

SELECT TRANSACTION_NAME,
             SUM (TRANSACTION_VALUE * EXCHANGE_RATE)
                 AS "REVENUE GBP"
        FROM TRANSACTION_TABLE S
             LEFT JOIN EXCHANGE_RATE C ON S.CURRENCY = C.FROM_CURRENCY AND C.TO_CURRENCY = 'GBP'
ORDER BY TRANSACTION_NAME

如果您的EXCHANGE_RATE表可以用完美元,那么您进行转换的时间就不会超过两个。 最多,您将转换为USD,然后再从USD转换为任何货币。 鉴于此,我只想为所有可能的情况编写代码,而不要尝试像CONNECT BY这样的幻想。

我认为“所有可能的情况”是:

  • 交易已使用目标货币
  • 交易使用可直接转换为目标货币的货币
  • 交易必须先转换为美元,然后再从美元转换为目标货币。

这是一个查询,将执行此操作。 WITH子句只是为了给它一些数据-它们不会成为您的解决方案的一部分,因为您有实际的表。

WITH rates ( from_currency, to_currency, exchange_rate ) AS 
( SELECT 'JPY', 'USD', 0.009 FROM DUAL UNION ALL
  SELECT 'GBP', 'USD', 1.31 FROM DUAL UNION ALL
  SELECT 'CNY', 'USD', 0.15 FROM DUAL UNION ALL
  SELECT 'JPY', 'CNY', 0.06 FROM DUAL),
txns ( transaction_name, transaction_value, currency ) AS
 ( SELECT 'txn 1 in JPY', 1000, 'JPY' FROM DUAL UNION ALL
   SELECT 'txn 2 in GBP', 1000, 'GBP' FROM DUAL UNION ALL
   SELECT 'txn 3 IN CNY', 1000, 'CNY' FROM DUAL UNION ALL
   SELECT 'txn 4 IN unknown', 1000, 'XXX' FROM DUAL),
params ( target_currency ) AS 
 ( SELECT 'CNY' FROM DUAL )
SELECT t.transaction_name,
       t.transaction_value base_value,
       t.currency base_currency,
       t.transaction_value * CASE WHEN t.currency = params.target_currency THEN 1
            WHEN r1.from_currency IS NOT NULL THEN r1.exchange_rate
            ELSE r2usd.exchange_rate / r2tar.exchange_rate END converted_value,
        params.target_currency converted_currency
FROM   params CROSS JOIN 
       txns t 
       LEFT JOIN rates r1 ON r1.from_currency = t.currency AND r1.to_currency = params.target_currency
       LEFT JOIN rates r2usd ON r2usd.from_currency = t.currency AND r2usd.to_currency = 'USD'
       LEFT JOIN rates r2tar ON r2tar.from_currency = params.target_currency AND r2tar.to_currency = 'USD'

我建议采取额外的步骤来扩展您的汇率表,并使用UDS作为转移货币来定义汇率。

此查询将添加通过USD计算的新汇率。 这是一个受限制的简单内部联接,因此计算是通过“ USD”进行的,而从和到货币则不同。 WHERE子句限制已知的组合。

select  er1.FROM_CURRENCY, er2.TO_CURRENCY,  er1.EXCHANGE_RATE * er2.EXCHANGE_RATE EXCHANGE_RATE
from exchange_rates er1
join exchange_rates er2
on er1.TO_CURRENCY = 'USD' and er2.FROM_CURRENCY = 'USD'  and er1.FROM_CURRENCY != er2.TO_CURRENCY
where (er1.FROM_CURRENCY, er2.TO_CURRENCY)
not in (select FROM_CURRENCY,   TO_CURRENCY from exchange_rates)

您可以定义一个物理新表或视图,甚至仅将其作为子查询执行,作为原始表的UNION ALL和该查询的结果。

您的最终查询将使用此扩展汇率表,而不是原始的汇率表。

这是我测试过的样本数据

create table exchange_rates
as
select 'GBP' FROM_CURRENCY,  'USD' TO_CURRENCY, 1.31  EXCHANGE_RATE from dual union all
select 'EUR' FROM_CURRENCY,  'USD' TO_CURRENCY, 1.16 EXCHANGE_RATE from dual union all
select 'AUD' FROM_CURRENCY,  'USD' TO_CURRENCY, .73 EXCHANGE_RATE from dual union all
select 'USD' FROM_CURRENCY,  'GBP' TO_CURRENCY, .76  EXCHANGE_RATE from dual union all
select 'USD' FROM_CURRENCY,  'EUR' TO_CURRENCY, .86 EXCHANGE_RATE from dual union all
select 'USD' FROM_CURRENCY,  'AUD' TO_CURRENCY, 1.36 EXCHANGE_RATE from dual union all
select 'GBP' FROM_CURRENCY,  'EUR' TO_CURRENCY, 1.12 EXCHANGE_RATE from dual;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM