未提供直接映射时的货币换算

时间:2018-02-08 13:43:38

标签: sql sql-server tsql

我有两张桌子@tbl_curr_master和@tbl_curr_trans b

我@tbl_curr_master,我拥有从每种货币到其他货币的主数据,其中包含源到目标货币的转换率。

第二个表,@ tbl_curr_trans我有一定数量的每种货币,我想将所有金额转换为EUR只在某些情况下映射直接提供 我可以在a.curr_name = b.from_curr的基础上直接加入,并且可以获得所需数据但在某些情况下不提供直接映射 就像INR到EUR一样,没有这样的直接映射,但我可以做的是我可以先计算USD然后计算EUR。

请建议如何在tsql查询中以有效的方式执行此操作。

declare @tbl_curr_master table (id int  ,from_curr char(5), to_curr char(5),conversion_rate float )

insert into @tbl_curr_master(id, from_curr,to_curr,conversion_rate)
values(1,'usd','eur',0.28999),(2,'inr','usd',2.3645),(3,'chk','eur',0.56977),(4,'chk','eur',0.56977)


declare @tbl_curr_trans table (id int , curr_name varchar(5), amount float)

insert into @tbl_curr_trans (id,curr_name, amount)
values(1,'inr',789000),(2,'usd',896666),(3,'chk',458888)


select a.id , a.curr_name ,b.to_curr,  a.amount/ b.conversion_rate
from @tbl_curr_trans a , @tbl_curr_master b 
where a.curr_name=b.from_curr  

1 个答案:

答案 0 :(得分:0)

几位评论:

  • 你最好使用#temp-tables而不是@ table-variables
  • 您可能最好使用JOIN构造而不是简单地列出FROM子句中的所有表格,然后在WHERE
  • 中将它们链接在一起
  • 您当前的构造只是根据发现转换,没有迹象表明您实际想要的目标货币

为此,我建议将数据转储到临时表中,并使用LEFT OUTER JOIN进行直接转换,然后进行更新以进行间接转换。

CREATE TABLE #curr_master  (id int  ,from_curr char(5), to_curr char(5),conversion_rate float )

INSERT INTO #curr_master  (id, from_curr,to_curr,conversion_rate)
VALUES (1,'usd','eur',0.28999),
       (2,'inr','usd',2.3645),
       (3,'chk','eur',0.56977),
       (4,'chk','eur',0.56977)

CREATE TABLE #curr_trans (id int , curr_name varchar(5), amount float)

INSERT INTO #curr_trans (id,curr_name, amount)
VALUES(1,'inr',789000),
      (2,'usd',896666),
      (3,'chk',458888)

DECLARE @target_curr char(5) = 'eur'

-- direct conversion
SELECT a.id , a.curr_name, to_curr = @target_curr, curr_amount = a.amount, to_amount = a.amount/ b.conversion_rate
INTO #result
from #curr_trans a 
LEFT OUTER JOIN #curr_master b 
             ON b.from_curr  =  a.curr_name
            AND b.to_curr = @target_curr


SELECT * FROM #result

-- update those we missed via usd
UPDATE #result
   SET to_amount = ( SELECT #result.curr_amount * to_usd.conversion_rate * to_eur.conversion_rate
                       FROM #curr_master to_usd, #curr_master to_eur
                      WHERE to_usd.from_curr = #result.curr_name
                        AND to_usd.to_curr = 'usd'
                        AND to_eur.from_curr = 'usd'
                        AND to_eur.to_curr   = @target_curr)
 WHERE to_amount IS NULL

SELECT * FROM #result

您可以在1个声明中执行此操作而无需#results,但是像这样更容易关注IMHO。

PS:同意,我的UPDATE也可以使用JOIN,但我认为它更像这样可读。 (每个规则都有例外=)