2012-07-30 39 views
2

我有一個表exchange_rate,它具有類似currA,currB,rate的條目。例如(不要理會率的準確度):用於計算同一表的列之間的關係的SQL查詢

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美元。例如,要將歐元兌換爲美元,我可以使用第4,9行。與將英鎊兌換爲美元類似,可以將第1行除以0.87(第2行的結果),也可以從第10行,第6行和第8行計算此比率。

是否有任何SQL查詢可以幫助我做到這一點?

+0

的什麼味道SQL?例如sql-server-2008? – 2012-07-30 13:16:13

+2

與查詢無關,但您是否總想將貨幣A直接轉換爲貨幣B?您擁有的貨幣之間的跳數越多,由於貨幣之間的匯率波動,最後的結果越不可能準確。今天考慮一下:將10美元兌換成歐元兌換英鎊會得到6.37382英鎊,但是將10美元兌換成英鎊會得到6.374英鎊。 – LittleBobbyTables 2012-07-30 13:16:56

+0

嗨。感謝您抽出時間。您的問題的答案是肯定的,我會直接將A轉換爲B,以防萬一它可用,就像您提到的美元兌英鎊的例子一樣。但對於我提到的例子,即歐元兌美元,不存在直接轉換可用ABD,不幸的是我不得不跳躍啤酒花。爲了添加更多的信息並且可能會有幫助,我需要在腳本中做到這一點。即使是一個子查詢和特定的代碼也可以完成這些工作,那麼這樣做也不錯。 – user1314305 2012-07-30 14:49:04

回答

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 

所以對於英鎊的結果 - >美元是1.01304

+0

哇..這是一些SQL的東西!將在早上嘗試第一件事。我將不得不尋找一些平行的,因爲我在我的工作場所使用informix sql。很多很多謝謝回答這個問題。 – user1314305 2012-07-30 16:48:00

+0

它是一個可怕的查詢,可能效率不高,但似乎適用於您提到的場景。 – 2012-07-30 17:03:39

+0

系統故障時無法驗證您的答案。不過,我仍然認爲這是正確的解決方案。謝謝你的幫助 – user1314305 2012-08-01 12:25:58

相關問題