<bdo id='88lci'></bdo><ul id='88lci'></ul>
        <legend id='88lci'><style id='88lci'><dir id='88lci'><q id='88lci'></q></dir></style></legend>

        <small id='88lci'></small><noframes id='88lci'>

        <tfoot id='88lci'></tfoot>
      1. <i id='88lci'><tr id='88lci'><dt id='88lci'><q id='88lci'><span id='88lci'><b id='88lci'><form id='88lci'><ins id='88lci'></ins><ul id='88lci'></ul><sub id='88lci'></sub></form><legend id='88lci'></legend><bdo id='88lci'><pre id='88lci'><center id='88lci'></center></pre></bdo></b><th id='88lci'></th></span></q></dt></tr></i><div id='88lci'><tfoot id='88lci'></tfoot><dl id='88lci'><fieldset id='88lci'></fieldset></dl></div>

        针对日期范围的 SQL 连接?

        时间:2023-10-09
        <i id='ylvc8'><tr id='ylvc8'><dt id='ylvc8'><q id='ylvc8'><span id='ylvc8'><b id='ylvc8'><form id='ylvc8'><ins id='ylvc8'></ins><ul id='ylvc8'></ul><sub id='ylvc8'></sub></form><legend id='ylvc8'></legend><bdo id='ylvc8'><pre id='ylvc8'><center id='ylvc8'></center></pre></bdo></b><th id='ylvc8'></th></span></q></dt></tr></i><div id='ylvc8'><tfoot id='ylvc8'></tfoot><dl id='ylvc8'><fieldset id='ylvc8'></fieldset></dl></div>

        1. <legend id='ylvc8'><style id='ylvc8'><dir id='ylvc8'><q id='ylvc8'></q></dir></style></legend>
            <tfoot id='ylvc8'></tfoot>
            • <small id='ylvc8'></small><noframes id='ylvc8'>

                  <tbody id='ylvc8'></tbody>
                  <bdo id='ylvc8'></bdo><ul id='ylvc8'></ul>
                  本文介绍了针对日期范围的 SQL 连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  考虑两个表:

                  交易,外币金额:

                       Date  Amount
                  ========= =======
                   1/2/2009    1500
                   2/4/2009    2300
                  3/15/2009     300
                  4/17/2009    2200
                  etc.
                  

                  汇率,主要货币(比如美元)的外币价值:

                  ExchangeRates, with the value of the primary currency (let's say dollars) in the foreign currency:

                       Date    Rate
                  ========= =======
                   2/1/2009    40.1
                   3/1/2009    41.0
                   4/1/2009    38.5
                   5/1/2009    42.7
                  etc.
                  

                  可以输入任意日期的汇率 - 用户可以每天、每周、每月或不定期地输入它们.

                  Exchange rates can be entered for arbitrary dates - the user could enter them on a daily basis, weekly basis, monthly basis, or at irregular intervals.

                  为了将外国金额转换为美元,我需要遵守以下规则:

                  In order to translate the foreign amounts to dollars, I need to respect these rules:

                  A.如果可能,请使用最近的先前汇率;所以 2/4/2009 的交易使用 2/1/2009 的汇率,而 3/15/2009 的交易使用 3/1/2009 的汇率.

                  A. If possible, use the most recent previous rate; so the transaction on 2/4/2009 uses the rate for 2/1/2009, and the transaction on 3/15/2009 uses the rate for 3/1/2009.

                  B.如果没有为前一个日期定义费率,请使用可用的最早费率.因此,2009 年 1 月 2 日的交易使用 2009 年 1 月的汇率,因为没有定义更早的汇率.

                  B. If there isn't a rate defined for a previous date, use the earliest rate available. So the transaction on 1/2/2009 uses the rate for 2/1/2009, since there isn't an earlier rate defined.

                  这有效...

                  Select 
                      t.Date, 
                      t.Amount,
                      ConvertedAmount=(   
                          Select Top 1 
                              t.Amount/ex.Rate
                          From ExchangeRates ex
                          Where t.Date > ex.Date
                          Order by ex.Date desc
                      )
                  From Transactions t
                  

                  ... 但是 (1) 似乎加入会更有效 &优雅,并且 (2) 它不处理上面的规则 B.

                  ... but (1) it seems like a join would be more efficient & elegant, and (2) it doesn't deal with Rule B above.

                  除了使用子查询来查找合适的费率之外,还有其他选择吗?有没有一种优雅的方法来处理规则 B,而不用束缚自己?

                  Is there an alternative to using the subquery to find the appropriate rate? And is there an elegant way to handle Rule B, without tying myself in knots?

                  推荐答案

                  您可以先对按日期排序的汇率进行自联接,这样您就可以知道每个汇率的开始和结束日期,而无需日期中的任何重叠或间隔(可以将其作为视图添加到您的数据库中 - 在我的情况下,我只是使用公共表表达式).

                  You could first do a self-join on the exchange rates which are ordered by date so that you have the start and the end date of each exchange rate, without any overlap or gap in the dates (maybe add that as view to your database - in my case I'm just using a common table expression).

                  现在将这些准备好的"费率与交易结合起来既简单又高效.

                  Now joining those "prepared" rates with the transactions is simple and efficient.

                  类似于:

                  WITH IndexedExchangeRates AS (           
                              SELECT  Row_Number() OVER (ORDER BY Date) ix,
                                      Date,
                                      Rate 
                              FROM    ExchangeRates 
                          ),
                          RangedExchangeRates AS (             
                              SELECT  CASE WHEN IER.ix=1 THEN CAST('1753-01-01' AS datetime) 
                                      ELSE IER.Date 
                                      END DateFrom,
                                      COALESCE(IER2.Date, GETDATE()) DateTo,
                                      IER.Rate 
                              FROM    IndexedExchangeRates IER 
                              LEFT JOIN IndexedExchangeRates IER2 
                              ON IER.ix = IER2.ix-1 
                          )
                  SELECT  T.Date,
                          T.Amount,
                          RER.Rate,
                          T.Amount/RER.Rate ConvertedAmount 
                  FROM    Transactions T 
                  LEFT JOIN RangedExchangeRates RER 
                  ON (T.Date > RER.DateFrom) AND (T.Date <= RER.DateTo)
                  

                  注意事项:

                  • 您可以将 GETDATE() 替换为遥远未来的日期,我在这里假设未来的汇率未知.

                  • You could replace GETDATE() with a date in the far future, I'm assuming here that no rates for the future are known.

                  规则 (B) 是通过将第一个已知汇率的日期设置为 SQL Server datetime 支持的最小日期来实现的,这应该(根据定义,如果它是类型您用于 Date 列)是可能的最小值.

                  Rule (B) is implemented by setting the date of the first known exchange rate to the minimal date supported by the SQL Server datetime, which should (by definition if it is the type you're using for the Date column) be the smallest value possible.

                  这篇关于针对日期范围的 SQL 连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:什么时候用LEFT JOIN,什么时候用INNER JOIN? 下一篇:评论和评论回复的mysql结构

                  相关文章

                • <legend id='khmJe'><style id='khmJe'><dir id='khmJe'><q id='khmJe'></q></dir></style></legend>

                  <small id='khmJe'></small><noframes id='khmJe'>

                      <bdo id='khmJe'></bdo><ul id='khmJe'></ul>
                  1. <i id='khmJe'><tr id='khmJe'><dt id='khmJe'><q id='khmJe'><span id='khmJe'><b id='khmJe'><form id='khmJe'><ins id='khmJe'></ins><ul id='khmJe'></ul><sub id='khmJe'></sub></form><legend id='khmJe'></legend><bdo id='khmJe'><pre id='khmJe'><center id='khmJe'></center></pre></bdo></b><th id='khmJe'></th></span></q></dt></tr></i><div id='khmJe'><tfoot id='khmJe'></tfoot><dl id='khmJe'><fieldset id='khmJe'></fieldset></dl></div>
                    <tfoot id='khmJe'></tfoot>