【问题标题】:SQL query to calculate relation among columns of same tableSQL查询计算同一张表的列之间的关系
【发布时间】:2012-07-30 13:04:50
【问题描述】:

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

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

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

【问题讨论】:

  • 什么味道的sql?例如 sql-server-2008?
  • 与查询无关,但您不是一直想从货币 A 直接转换为货币 B 吗?您拥有的货币之间的跳数越多,由于货币之间的汇率波动,最后的结果就越有可能变得不精确。以今天为例:将 10 美元兑换为欧元为 GBP,您可以获得 6.37382 英镑,但将 10 美元兑换为 GBP 可获得 6.374 英镑。
  • 嗨。感谢您抽出时间来解决这个问题。您的问题的答案是肯定的,我会直接将 A 转换为 B,以防它像您提到的美元兑英镑示例那样可用。但是对于我提到的例子,即欧元到美元,没有可用的直接转换,不幸的是我不得不跳跳。要添加更多信息并且可能是这个 vcan 帮助,我需要在脚本中执行此操作。所以即使是子查询和某些 sript 代码也可以执行此操作,那也会很好。

标签: sql join


【解决方案1】:

使用递归 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

【讨论】:

  • 哇.. 那是一些 sql 的东西!!会在早上尝试第一件事。当我在工作场所使用informix sql时,我将不得不为此寻找一些并行。非常感谢您回答这个问题。
  • 这是一个可怕的查询,可能效率不高,但似乎适用于您提到的场景。
  • 系统出现故障时无法验证您的答案。但是,我仍然将其标记为正确的解决方案。感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-29
  • 2022-07-06
相关资源
最近更新 更多