如何在SQL中生成所有可能的汇率组合
给出一个货币和汇率元组表,如下所示:如何在SQL中生成所有可能的汇率组合,sql,sql-server-2005,join,tuples,Sql,Sql Server 2005,Join,Tuples,给出一个货币和汇率元组表,如下所示: EUR CHF 1.20 USD EUR 0.80 CHF JPY 1.30 如何简单地生成货币(A,B)和(B,A)之间的所有汇率 我希望有以下资料: EUR CHF CHF EUR EUR USD USD EUR USD CHF CHF USD 对于所有可能的组合,也就是说,可以通过链接多个费率来推导费率 A to B * B to C * C to D = A to D 我能找到的唯一方法是使用循环,我下面的所有查询都使用此示例数据: DEC
EUR CHF 1.20
USD EUR 0.80
CHF JPY 1.30
如何简单地生成货币(A,B)和(B,A)之间的所有汇率
我希望有以下资料:
EUR CHF
CHF EUR
EUR USD
USD EUR
USD CHF
CHF USD
对于所有可能的组合,也就是说,可以通过链接多个费率来推导费率
A to B * B to C * C to D = A to D
我能找到的唯一方法是使用循环,我下面的所有查询都使用此示例数据:
DECLARE @T TABLE (FromCurrency VARCHAR(3), ToCurrency VARCHAR(3), ExchangeRate DECIMAL(10, 5));
INSERT @T VALUES
('EUR', 'CHF', 1.20),
('USD', 'EUR', 0.80),
('CHF', 'JPY', 1.30);
第一步是获得所有的互惠汇率(即A->B表格中的B->A),因为这些是最容易获得的:
DECLARE @TempExchangeRates TABLE (FromCurrency VARCHAR(3), ToCurrency VARCHAR(3), ExchangeRate DECIMAL(10, 5));
INSERT @TempExchangeRates (FromCurrency, ToCurrency, ExchangeRate)
SELECT FromCurrency, ToCurrency, ExchangeRate
FROM @T
UNION
SELECT ToCurrency, FromCurrency, CAST(1 / ExchangeRate AS DECIMAL(10, 5))
FROM @T t
WHERE NOT EXISTS
( SELECT 1
FROM @T t2
WHERE t.FromCurrency = t2.ToCurrency
AND t.ToCurrency = t2.FromCurrency
)
在这一点上,我们有:
CHF EUR 0.83333
CHF JPY 1.30000
EUR CHF 1.20000
EUR USD 1.25000
JPY CHF 0.76923
USD EUR 0.80000
所以我们仍然失踪
CHF --> USD
EUR --> JPY
JPY --> CHF
JPY --> EUR
USD --> EUR
您需要继续执行此连接
SELECT a.FromCurrency, b.ToCurrency, CAST(a.ExchangeRate * b.ExchangeRate AS DECIMAL(10, 5))
FROM @TempExchangeRates a
INNER JOIN @TempExchangeRates b
ON a.ToCurrency = b.FromCurrency
AND a.FromCurrency != b.ToCurrency
WHERE NOT EXISTS
( SELECT 1
FROM @TempExchangeRates c
WHERE a.FromCurrency = c.FromCurrency
AND b.ToCurrency = c.ToCurrency
)
并插入结果,直到找到所有组合:
WHILE (1 = 1)
BEGIN
INSERT @TempExchangeRates (FromCurrency, ToCurrency, ExchangeRate)
SELECT DISTINCT a.FromCurrency, b.ToCurrency, CAST(a.ExchangeRate * b.ExchangeRate AS DECIMAL(10, 5))
FROM @TempExchangeRates a
INNER JOIN @TempExchangeRates b
ON a.ToCurrency = b.FromCurrency
AND a.FromCurrency != b.ToCurrency
WHERE NOT EXISTS
( SELECT 1
FROM @TempExchangeRates c
WHERE a.FromCurrency = c.FromCurrency
AND b.ToCurrency = c.ToCurrency
)
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END
END
在第一个循环中,它将检索
CHF USD 1.04166
EUR JPY 1.56000
JPY EUR 0.64102
USD CHF 0.96000
然后在第二天
JPY USD 0.80128
USD JPY 1.24800
然后将找到所有12个元组。您可以使用
设置:
Create Table ExchangeRates (
FromCurrency char(3),
ToCurrency char(3),
Rate decimal(10, 2),
Constraint PK_ExchangeRates Primary Key (FromCurrency, ToCurrency)
);
Create Index IX_ToCurrency On ExchangeRates(ToCurrency, FromCurrency, Rate);
Insert Into ExchangeRates (FromCurrency, ToCurrency, Rate) Values
('EUR', 'CHF', 1.20),
('USD', 'EUR', 0.80),
('CHF', 'JPY', 1.30);
CTE,假定所有货币代码正好是三个字符:
With AllExchanges as (
Select
FromCurrency,
ToCurrency,
Rate
From
ExchangeRates
Union
Select
ToCurrency,
FromCurrency,
Cast(1.0 / Rate As Decimal(10, 2))
From
ExchangeRates
)
, Paths as (
Select
FromCurrency,
cast(FromCurrency as varchar(max)) As ExchangePath,
ToCurrency,
Rate
From
AllExchanges a
Union All
Select
p.FromCurrency,
p.ExchangePath + ',' + p.ToCurrency,
a.ToCurrency,
Cast(p.Rate * a.Rate as Decimal(10, 2))
From
Paths p
Inner Join
AllExchanges a
On p.ToCurrency = a.FromCurrency
Where
p.ExchangePath Not Like '%' + a.ToCurrency + '%'
)
Select
FromCurrency,
ExchangePath + ',' + ToCurrency As ExchangePath,
ToCurrency,
Rate
From
Paths
但您可能需要计算两种货币之间的最短路径?问题的大小可以忽略,但最短路径当然更好。
EUR-CHF
可能不是CHF-EUR
的反比?i、 e.如果价格存在价差,最短路径将是关键,对吗?您使用的是什么DBMS?通过链接,这些费率为您提供1.248美元->日元,因此链的长度将引入舍入问题(我相信您有三个以上的费率)或矛盾的结果,其中两条不同的路线产生不同的结果。