2

我有一个表,其中包含, ,exchange_rate之类的条目。例如(不要担心费率的准确性):currAcurrBrate

currA       currB    rate   rowId
 USD         USD     1        1
 USD         GBP     0.87     2
 ZWD         EUR     0.5      3
 EUR         KRN     1.5      4
 RUP         USD     0.78     5
 YEN         FRA     0.67     6
 INR         RUP     1.3      7
 FRA         USD     1.08     8
 KNR         USD     0.76     9
 GBP         YEN     1.4     10

rate 显示currAwrt的转换率currB。示例:第二行表示1 USD = 0.87 GBP

现在,我想要每种货币兑美元的汇率。例如,要将 EUR 转换为 USD,我可以使用第 4、9 行。类似地,将 GBP 转换为 USD 可以将 1 除以 0.87(第 2 行的结果),或者我可以从第 10、6 和 8 行计算这个汇率。

是否有任何 SQL 查询可以帮助我做到这一点?

4

1 回答 1

3

使用递归 CTE 可以获得结果,但如果您不使用 sql-server(2005 或更高版本),这可能不起作用。

declare @data table (currA varchar(3), currB varchar(3), rate decimal(4,2), rowId int)
insert into @data values
('USD', 'USD', 1, 1),
('USD', 'GBP', 0.87, 2),
('ZWD', 'EUR', 0.5, 3),
('EUR', 'KRN', 1.5, 4),
('RUP', 'USD', 0.78, 5),
('YEN', 'FRA', 0.67, 6),
('INR', 'RUP', 1.3, 7),
('FRA', 'USD', 1.08, 8),
('KRN', 'USD', 0.76, 9),
('GBP', 'YEN', 1.4, 10)

-- GBP to USD
-- EUR to USD
declare @from varchar(3) = 'GBP'
declare @to varchar(3) = 'USD'

;with cte as
(
    select
        lvl = 1,
        rt.currA,
        rt.currB,
        rt.rate,
        rt.rowId
    from @data rt
    where rt.currA = @from

    union all

    select
        lvl = t.lvl + 1,
        ct.currA,
        ct.currB,
        ct.rate,
        ct.rowId
    from @data ct
    inner join cte t on t.currB = ct.currA
    where ct.currA <> ct.currB
    and ct.currB <> @to 
)

select @from, @to, exp(sum(log(rate)))
from
(
select currA, currB, rate, rowId from cte
union all 
select currA, currB, rate, rowId 
from @data 
where currA in 
(
    select cte.currB 
    from cte 
    where lvl in 
    (
        select MAX(lvl) 
        from cte
    )
) and currB = @to
)t

所以 GBP -> USD 的结果是 1.01304

于 2012-07-30T14:57:44.070 回答