用于计算同一列的列之间关系的SQL查询

时间:2012-07-30 13:04:51

标签: sql join

我有一个表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 w.r.t的转换率。 currB。示例:第二行表示1 USD = 0.87 GBP

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

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

1 个答案:

答案 0 :(得分: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的结果 - &gt;美元是1.01304