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

currAレートは、 wrtの変換レートを示しますcurrB。例:2行目は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 に答える