【问题标题】:Update table by join通过连接更新表
【发布时间】:2012-08-25 11:42:21
【问题描述】:

我有一张如下所示的汇率表

FromCurrency    ToCurrency          ValidFrom               ExchangeRate
USD             ZAR         2012-01-05 00:00:00.000         7.7260000000
USD             ZAR         2012-01-04 00:00:00.000         7.6740000000
USD             ZAR         2012-01-03 00:00:00.000         7.4601000000
USD             ZAR         2012-01-02 00:00:00.000         7.7600000000
USD             ZAR         2012-01-01 00:00:00.000         8.0945000000
EUR             NOK         2012-01-05 00:00:00.000         7.5881000000
EUR             NOK         2012-01-04 00:00:00.000         7.5974000000
EUR             NOK         2012-01-03 00:00:00.000         7.4494000000
EUR             NOK         2012-01-02 00:00:00.000         7.6606000000
EUR             NOK         2012-01-01 00:00:00.000         7.7740000000
USD             AED         2012-01-05 00:00:00.000         3.6731000000
USD             AED         2012-01-04 00:00:00.000         3.6731000000

我的主表是

Transaction Date    Amount  Currency    FromCurrency
13971   5/27/2011    8000     USD   USD
13971   7/31/2011   -6809.4   ZAR   USD
13971   8/30/2011   -425.59   ZAR   USD
13971   9/27/2011   -6809.4   ZAR   USD
67467   11/8/2011    5000     GBP   GBP
67467   12/21/2011  -5195.06  ZAR   GBP
67467   1/30/2012   -5195.06  ZAR   GBP
81181   4/15/2011    6000     USD   USD
81181   6/28/2011   -5159.03  ZAR   USD
82418   10/21/2011   5000     EUR   EUR
82418   1/27/2012   -3919.97  NOK   EUR

以上是表的示例数据,我的实际表有数百万条记录。我必须将金额与汇率列(来自汇率表)相乘,并用我表中的货币列更新相应的 FromCurrency(来自汇率表)。

我尝试了很多方法,但找不到解决方案。这里的棘手部分是我的表在汇率表中没有匹配的日期。

应该这样应用汇率。如果我的交易日期是 2012 年 2 月 20 日,货币是 ZAR,FromCurrency 是美元,那么我必须从汇率表中选择下面一行

USD             ZAR         2012-01-02 00:00:00.000         7.7600000000

【问题讨论】:

  • 你能告诉我你的输出表是什么?
  • @AnandPhadke myoutput 表与我的主表相同。我必须更新金额和货币列。

标签: sql sql-server-2008


【解决方案1】:
update transactions
set FromCurrencyAmount = transactions.amount * 
    (select top 1 exchangerate from exchangerates where validfrom <= transactions.date 
       and transactions.fromcurrency = exchangerates.fromcurrency
       and transactions.currency = exchangerates.tocurrency
       order by validfrom desc) 

选择

select transactions.*, 
    (select top 1 exchangerate from exchangerates where validfrom <= transactions.date 
       and transactions.fromcurrency = exchangerates.fromcurrency
       and transactions.currency = exchangerates.tocurrency
       order by validfrom desc) 
from transactions

【讨论】:

  • 你能给出这个查询的选择版本吗?我想在实际更新我的主表之前选择汇率并查看。非常感谢您的回答。
  • @poduluska 非常感谢,我真的无法将该语句转换为 select 语句。在 SQL 中要学习的东西太多了!
  • @poduluska 我注意到这个查询让我从所选存储桶中获得最高汇率。对于美元兑南非兰特,如果我有 2012 年 3 月 1 日、2012 年 5 月 1 日、2012 年 6 月 1 日的汇率。即使我的交易日期是 2012 年 4 月 1 日,查询也会得到 2012 年 6 月 1 日的汇率。
  • 它应该得到2012年4月11日交易的2012年3月1日汇率和2012年5月21日交易的2012年5月1日汇率。但此查询仅获得 2012 年 6 月 1 日汇率(桶中顶部)的汇率。
  • @Nani 您要么奇怪地存储了日期,要么错误地转置了查询。
【解决方案2】:

另一种选择是:

select * from
transact t1 join exchRate e1 on t1.FromCurrency = e1.FromCurrency 
and t1.ToCurrency = e1.ToCurrency
and t1.tdate > e1.ValidFrom 
and not exists 
(select 1 from exchRate where ValidFrom < t1.tdate and ValidFrom > e1.ValidFrom) 

【讨论】:

  • 感谢您的回答。我也遇到了与下面提到的这种方法相同的问题。对于美元兑南非兰特,如果我有 2012 年 3 月 1 日、2012 年 5 月 1 日、2012 年 6 月 1 日的汇率。即使我的交易日期是 2012 年 4 月 11 日或 2012 年 5 月 21 日,查询也会得到我 2012 年 6 月 1 日的汇率。它应该得到 2012 年 4 月 11 日交易的 2012 年 3 月 1 日汇率和 2012 年 5 月 21 日交易的 2012 年 5 月 1 日汇率。
  • 我认为您对日期格式感到困惑(例如 01/03/2012 可能是 1-Mar-2012 或 3-Jan-2012 )
  • 你是绝对正确的。汇率表日期采用英国格式,我的主表日期列采用美国格式。对不起,我纠正了错误。谢谢。
【解决方案3】:

希望理解

 SELECT T3.*,
   T4.DATEMAX,
   T4.VALUESELECTED
   FROM   TRANSACTIONS AS T3
   INNER JOIN
   (SELECT T.CURRENCY,
           T.FROMCURRENCY,
           T.DATEMAX,
           T2.EXCHANGERATE AS VALUESELECTED
    FROM   (SELECT   CURRENCY,
                     FROMCURRENCY,
                     MAX(ValidFrom) AS DATEMAX
            FROM     ExChangeRate
            WHERE    ValidFrom <= T3.DATE
            GROUP BY Currency, FromCurrency) AS T
           INNER JOIN
           ExChangeRate AS T2
           ON T.CURRENCY = T2.CURRENCY
              AND T.FROMCURRENCY = T2.FROMCURRENCY
              AND T.DATEMAX = T2.VALIDFROM) AS T4
   ON T4.CURRENCY = T3.CURRENCY
      AND T4.FROMCURRENCY = T3.FROMCURRENCY;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    相关资源
    最近更新 更多