为什么我的存储过程有时会添加列错误?

时间:2015-01-27 10:52:58

标签: sql sql-server tsql sql-server-2012

我将此查询写入列,即运行记录,即Ledger。

例如:

Amount  --  RunningAmount
-------------------------
200     --  500
200     --  700
500     --  1200
120     --  1320

正如您所看到的,运行金额是运行金额与每行金额之间相加的结果。

我写了这个查询,但效果很好。

ALTER PROCEDURE [dbo].[Rpt_Ledger]
    @FromDate datetime='1/26/2015',
    @ToDate datetime='1/26/2015',
    @AccountID int=17
AS
BEGIN
    Begin Try
         SELECT 
             A.AccountID, AccountTitle, Null AS TranasactionDateTime, 
             0 AS Amount,'Opening Balance' as [Description],
             SUM(T.Amount) AS RunningAmount
         FROM 
             Payments.Accounts A 
         INNER JOIN 
             Payments.Transactions T ON A.AccountID = T.Account_ID
         WHERE 
             T.Account_ID = @AccountID 
             AND T.DateTime < CONVERT(smalldatetime, @fromDate)
         GROUP BY 
             A.AccountID, A.AccountTitle 

         UNION 

         SELECT 
             A.AccountID, A.AccountTitle, A.TranasactionDateTime, 
             A.Amount, A.[Description], A.RunningAmount 
         FROM 
             (SELECT 
                  A.AccountID, A.AccountTitle, 
                  T.DateTime AS TranasactionDateTime, T.Amount, T.[Description],
                     SUM(T.Amount) OVER (PARTITION BY T.Account_Id ORDER BY T.DateTime ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 
                     AS RunningAmount     
              FROM Payments.Accounts A 
              INNER JOIN Payments.Transactions T ON A.AccountID = T.Account_ID
              WHERE T.Account_ID = @AccountID
             ) AS A 
        WHERE A.TranasactionDateTime >= CONVERT(smalldatetime, @fromDate) AND A.TranasactionDateTime< CONVERT(smalldatetime,DATEADD(day,1, @toDate))

    End Try
    Begin Catch
            Select ERROR_MESSAGE() as ErrMsg
    End Catch

END

但是我发现了一个问题,它产生了数百条记录,但我认为某些值错了

AMOUNT      RUNNINGAMOUNT

200.00      57300.00
200.00      57500.00
500.00      54800.00
500.00      56100.00
200.00      57700.00
200.00      58100.00
200.00      57900.00
200.00      58300.00

你可以看到它已经开始在某些时候错误地添加,之后它再次添加好了,为什么?为什么它在一定程度上运作良好然后又错了又一次呢?

帮助

2 个答案:

答案 0 :(得分:0)

单个Payments.Accounts.DateTime有多个记录。不确定Payments.Transactions是否有TransactionId列。如果是,你可以写

SUM(T.Amount) OVER (
    PARTITION BY T.Account_Id 
    ORDER BY T.DateTime, T.TransactionId
)

答案 1 :(得分:0)

您的查询缺少ORDER BY子句,因此结果可能恰好按顺序排列(因为必须以某种方式完成某些排序以获得运行总计),但这绝不是保证。

所以你必须添加一个ORDER BY子句,一切都应该没问题。

SELECT 
  ...
ORDER BY 
  AccountID, 
  CASE WHEN TranasactionDateTime IS NULL THEN 0 ELSE 1 END, -- NULLs first
  TranasactionDateTime;

为什么这个UNION顺便说一下?这不应该是UNION ALL吗?可以删除任何重复的行吗?