簡體   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