从最近的可用日期检索值

时间:2013-07-16 16:07:23

标签: sql tsql

我有一个系统,它在历史表中存储余额的历史记录。 该表包含帐号,分类代码,余额,余额开始日期,余额结束日期。 更新余额时,会在历史记录表中创建一个条目,该条目显示余额,余额首次开始时的日期和余额变更日期。因此,例如,该表将显示$ 100.00的余额,此余额从2013年10月7日到2013年7月15日。

我要做的是获取特定日期所有排序代码的余额总和,但余额可能在此日期没有变化,所以我需要返回最接近的日期,但我失败了。

这是我到目前为止所尝试的。

declare @sdate datetime
set @sdate = '06/08/2012' --mm/dd/yyyy

SELECT CONVERT(varchar(20),MAX(StartDate),103) as "Closest Start Date",  Sort, SUM(Balance) AS "Sum of balances"
    FROM BalanceHistory
        WHERE StartDate <= convert(smalldatetime ,@sdate) AND SortCode <> 'ABC123456'
            GROUP BY SortCode

SELECT FROM BalanceHistory会产生类似

的东西
AccountNumber, SortCode, Balance, StartDate, EndDate, RECID
00000001, srt010203, 100.00, 06/01/2013, 06/02/2013,  RECID
00000001, srt010203, 110.00, 06/02/2013, 06/03/2013,  RECID
00000001, srt010203, 120.00, 06/03/2013, 06/04/2013,  RECID
00000002, srt010204, 200.00, 06/01/2013, 06/02/2013,  RECID
00000003, srt010204, 300.00, 06/01/2013, 06/02/2013,  RECID
00000004, srt010205, 400.00, 06/01/2013, 06/02/2013,  RECID
00000005, srt010205, 500.00, 06/01/2013, 06/02/2013,  RECID

2 个答案:

答案 0 :(得分:1)

您可以使用JOIN函数(假设SQL Server 2005或更高版本)在没有ROW_NUMBER()的情况下执行此操作:

DECLARE @sdate DATE
SET @sdate = '2012-06-08'
SELECT SortCode, SUM(Balance)'Sum of Balances'
FROM (SELECT AccountNumber,SortCode, Balance,ROW_NUMBER() OVER (PARTITION BY AccountNumber ORDER BY StartDate DESC)'RowRank'
        FROM BalanceHistory
        WHERE StartDate <= @sdate AND SortCode <> 'ABC123456'
     )sub
WHERE RowRank = 1
GROUP BY SortCode

演示:SQL Fiddle

子查询中的ROW_NUMBER()函数为每个帐号的余额分配一个'RowRank',我们按StartDate DESC订购,以获得每个帐号的最新余额的等级'1',WHERE标准限制它是您在变量中设置的日期之间的最新余额。然后,您在外部查询中使用该排名仅限制为该一个余额。

答案 1 :(得分:0)

这应该有效

Declare @table as table
(AccountNo int,
 Balance money,
 DateEntered datetime)

 Declare @dt datetime

 set @dt = '2013-07-01'
 Insert into @table values(1, 100, '2013-04-01')
Insert into @table values(2, 200, '2013-04-01')
Insert into @table values(2, 300, '2013-05-01')
Insert into @table values(2, 400, '2013-06-01')
  --select AccountNo, Max(Balance), Max(DateEntered) MaxDateEntered From @table where DateEntered <= @dt  group by AccountNo 


Select Sum(t.Balance) From @table t
inner join (select AccountNo, Max(Balance) Balance, Max(DateEntered) MaxDateEntered From @table where DateEntered <= @dt  group by AccountNo) tm
on t.AccountNo = tm.AccountNo and t.DateEntered = tm.MaxDateEntered

    enter code here