【问题标题】:SQL Account Balance TableSQL 账户余额表
【发布时间】:2016-09-23 12:41:45
【问题描述】:

我有一个程序的流动账户余额,它根据用户的交易进行更新。从这里我想加入一个表,其中包含每个用户的行和程序历史的每个日期,这样我就可以了解余额的分布如何随时间变化。

交易余额数据Ex.1(这是日终余额):

userId  transDate   userBalance
33782   2016-05-13  233
33783   2016-05-13  143
30070   2016-05-20  572
30071   2016-05-20  888

例如。 2的日历表

userID  balanceDate 
33782   2016-05-13 
33783   2016-05-13 
30070   2016-05-13 
30071   2016-05-13 
33782   2016-05-20  
33783   2016-05-20  
30070   2016-05-20  
30071   2016-05-20  

想要的结果

userId  balanceDate userBalance 
33782   2016-05-13  233 
33783   2016-05-13  143 
30070   2016-05-13  0
30071   2016-05-13  0 
33782   2016-05-20  233 
33783   2016-05-20  143 
30070   2016-05-20  572 
30071   2016-05-20  888

基本上,我需要以某种方式将事务表连接到 calendarBalance 表,并让 userBalance 字段返回最大记录记录,其中 transDate 小于或等于 balanceDate 否则为 0。 由于数据库有数百万笔交易,我所做的每一次尝试都会超时。 我正在使用 SQL Server 2012。

这是一个超时的尝试:

SELECT d.balanceDate ,b.userId ,b.userBalance 
FROM #calendar d ,#userBalance b 
WHERE d.balanceDate >= b.transDate 
AND b.transDate >= ALL ( 
 SELECT b1.transDate 
 FROM #userBalance b1 
 WHERE b.userId = b1.userId 
 AND d.transDate >= b1.transDate 
) 
ORDER BY d.balanceDate ,b.userId

【问题讨论】:

  • 一个用户一天内有多笔交易怎么办?
  • 交易表是日期的总和
  • 这是一个很好的起点。 spaghettidba.com/2015/04/24/…
  • 您能否发布一个超时的尝试,以便我们帮助调试它?
  • @TabAlleman SELECT d.balanceDate ,b.userId ,b.userBalance FROM #calendar d ,#userBalance b WHERE d.balanceDate >= b.transDate AND b.transDate >= ALL ( SELECT b1. transDate FROM #userBalance b1 WHERE b.userId = b1.userId AND d.transDate >= b1.transDate ) ORDER BY d.balanceDate ,b.userId

标签: sql-server


【解决方案1】:
Declare @Transaction table (UserID int,TransDate Date,UserBalance int)
Insert into @Transaction Select 33782,'2016-05-13',233
Insert into @Transaction Select 33783,'2016-05-13',143
Insert into @Transaction Select 30070,'2016-05-20',572
Insert into @Transaction Select 30071,'2016-05-20',888

Declare @Calendar table (UserID int,BalanceDate date)
Insert into @Calendar Select 33782,'2016-05-13'
Insert into @Calendar Select 33783,'2016-05-13' 
Insert into @Calendar Select 30070,'2016-05-13'
Insert into @Calendar Select 30071,'2016-05-13' 
Insert into @Calendar Select 33782,'2016-05-20'  
Insert into @Calendar Select 33783,'2016-05-20'  
Insert into @Calendar Select 30070,'2016-05-20'  
Insert into @Calendar Select 30071,'2016-05-20'  



Select A.*,UserBalance=isnull((Select top 1 UserBalance From @Transaction Where UserID=A.UserID and TransDate<=A.BalanceDate Order by TransDate Desc),0)
 From (
        Select UserID,balanceDate
         From (Select Distinct UserID from @Calendar) U
         Join (Select Distinct balanceDate  from @Calendar) C on 1=1
      ) A
 Order by 2,1 Desc

返回

UserID  balanceDate UserBalance
33783   2016-05-13  143
33782   2016-05-13  233
30071   2016-05-13  0
30070   2016-05-13  0
33783   2016-05-20  143
33782   2016-05-20  233
30071   2016-05-20  888
30070   2016-05-20  572

【讨论】:

  • 我应该补充一点,我不知道这在 LARGE 数据集上的表现如何。如果效果不好,请告诉我
  • 我检查了这个并且它有效!性能方面,处理 1460 万条记录需要 8 分 9 秒。鉴于日历表的大小(约 3 亿行),这将需要一段时间,我可能只需要分批运行。我计划只运行一次此查询以创建初始表,然后每晚运行更新脚本以获取新记录。感谢您的帮助!
  • 好吧,我没想到有 300MM 行。如果这是一个常规请求,我不会容忍 8 分钟,请告诉我是否可以帮助调整。选择前 1 名将是杀手。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-09
  • 1970-01-01
  • 2016-10-11
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多