SQL 视图中的运行总计

发布于 2024-12-08 14:15:51 字数 1993 浏览 0 评论 0原文

我试图在 SQL Server 2008 的视图中获取运行总计

这是我的表

BankAccounts
------------
AccountID (KEY)
Name
Created

Transactions
------------
TransactionID (KEY)
Description
Credit
Debit
TransDate
Created
AccountID

这是迄今为止我的查询..

SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, ba.AccountID,
        (isnull(t.Credit,0)-isnull(t.Debit,0))+COALESCE((SELECT SUM(isnull(Credit,0)) - SUM(isnull(Debit,0))
                              FROM Transactions b 
                              WHERE b.TransDate < t.TransDate
                               and b.AccountID = t.AccountID),0)
                                 AS RunningTotal
FROM  Transactions t 
INNER JOIN dbo.BankAccounts ba ON t.AccountID = ba.AccountID

我得到的是..

TransDate               Credit                 Debit                  RunningTotal
----------------------- ---------------------- ---------------------- ---------------------
2011-10-08 20:14:00     NULL                   12                     49.25
2011-10-08 20:14:00     2.11                   NULL                   63.36
2011-10-07 20:14:00     42.25                  NULL                   61.25
2011-10-06 20:14:00     NULL                   12.25                  19
2011-10-05 20:14:00     31.25                  NULL                   31.25

它应该是什么样子...

TransDate               Credit                 Debit                  Running Total
----------------------- ---------------------- ---------------------- ---------------------
2011-10-08 00:31:32.957 NULL                   12                     51.36
2011-10-08 00:31:32.957 2.11                   NULL                   63.36
2011-10-07 00:31:32.957 42.25                  NULL                   61.25
2011-10-06 00:31:32.957 NULL                   12.25                  19
2011-10-05 00:31:32.960 31.25                  NULL                   31.25

我真的很接近..只是似乎当同一天有两笔交易时,它没有正确计算..有什么想法吗?

I am trying to get running totals in my View in SQL Server 2008

Here is my tables

BankAccounts
------------
AccountID (KEY)
Name
Created

Transactions
------------
TransactionID (KEY)
Description
Credit
Debit
TransDate
Created
AccountID

Here is my query so far..

SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, ba.AccountID,
        (isnull(t.Credit,0)-isnull(t.Debit,0))+COALESCE((SELECT SUM(isnull(Credit,0)) - SUM(isnull(Debit,0))
                              FROM Transactions b 
                              WHERE b.TransDate < t.TransDate
                               and b.AccountID = t.AccountID),0)
                                 AS RunningTotal
FROM  Transactions t 
INNER JOIN dbo.BankAccounts ba ON t.AccountID = ba.AccountID

What I'm getting is..

TransDate               Credit                 Debit                  RunningTotal
----------------------- ---------------------- ---------------------- ---------------------
2011-10-08 20:14:00     NULL                   12                     49.25
2011-10-08 20:14:00     2.11                   NULL                   63.36
2011-10-07 20:14:00     42.25                  NULL                   61.25
2011-10-06 20:14:00     NULL                   12.25                  19
2011-10-05 20:14:00     31.25                  NULL                   31.25

What it should look like...

TransDate               Credit                 Debit                  Running Total
----------------------- ---------------------- ---------------------- ---------------------
2011-10-08 00:31:32.957 NULL                   12                     51.36
2011-10-08 00:31:32.957 2.11                   NULL                   63.36
2011-10-07 00:31:32.957 42.25                  NULL                   61.25
2011-10-06 00:31:32.957 NULL                   12.25                  19
2011-10-05 00:31:32.960 31.25                  NULL                   31.25

I'm really close.. just seems when there are 2 transactions for same day, it doesn't calculate it correctly.. any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

伊面 2024-12-15 14:15:51

因为您是 2008 年,所以我使用了 ROW_NUMBERCTE

WITH transactionTotal AS
(
   SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, a.AccountID
      , ROW_NUMBER() OVER (ORDER BY TransDate ASC) AS RowNumber
      , ( ISNULL(t.Credit, 0) - ISNULL(t.Debit, 0) ) AS TransactionTotal
   FROM dbo.Transactions AS t 
   INNER JOIN dbo.BankAccounts AS a ON t.AccountID = a.AccountID
)
SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, t.AccountID
   , ( SELECT SUM(tt.TransactionTotal)
       FROM transactionTotal AS tt
       WHERE tt.RowNumber <= t.RowNumber) AS RunningTotal
FROM transactionTotal AS t
LEFT JOIN transactionTotal AS tt ON t.RowNumber = tt.RowNumber + 1
ORDER BY t.TransDate DESC

I used ROW_NUMBER AND a CTE since you're in 2008

WITH transactionTotal AS
(
   SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, a.AccountID
      , ROW_NUMBER() OVER (ORDER BY TransDate ASC) AS RowNumber
      , ( ISNULL(t.Credit, 0) - ISNULL(t.Debit, 0) ) AS TransactionTotal
   FROM dbo.Transactions AS t 
   INNER JOIN dbo.BankAccounts AS a ON t.AccountID = a.AccountID
)
SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, t.AccountID
   , ( SELECT SUM(tt.TransactionTotal)
       FROM transactionTotal AS tt
       WHERE tt.RowNumber <= t.RowNumber) AS RunningTotal
FROM transactionTotal AS t
LEFT JOIN transactionTotal AS tt ON t.RowNumber = tt.RowNumber + 1
ORDER BY t.TransDate DESC
七禾 2024-12-15 14:15:51
SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, ba.AccountID,
       coalesce((select sum(ISNULL(Credit,0) - ISNULL(Debit, 0)) 
                 from Transactions
                 where TransactionID <= t.TransactionID and 
                       AccountID = ba.AccountID and
                      convert(date, TransDate) = convert(date, t.TransDate)),0)
        AS [Running Total]

FROM  Transactions t INNER JOIN
         dbo.BankAccounts ba ON t.AccountID = ba.AccountID
SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, ba.AccountID,
       coalesce((select sum(ISNULL(Credit,0) - ISNULL(Debit, 0)) 
                 from Transactions
                 where TransactionID <= t.TransactionID and 
                       AccountID = ba.AccountID and
                      convert(date, TransDate) = convert(date, t.TransDate)),0)
        AS [Running Total]

FROM  Transactions t INNER JOIN
         dbo.BankAccounts ba ON t.AccountID = ba.AccountID
提赋 2024-12-15 14:15:51

--我将使用现有的身份列来 100% 确定我正在处理正确的事务。

SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, ba.AccountID,
        (isnull(t.Credit,0)-isnull(t.Debit,0))+COALESCE((SELECT SUM(isnull(Credit,0)) - SUM(isnull(Debit,0))
                              FROM Transactions b 
                              WHERE b.TransactionID < t.TransactionID 
                               and b.AccountID = t.AccountID),0)
                                 AS RunningTotal
FROM  Transactions t 
INNER JOIN dbo.BankAccounts ba ON t.AccountID = ba.AccountID

--此外,如果将“小于”更改为“小于或等于”,则不必添加当前项目:

SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, ba.AccountID,
COALESCE((SELECT SUM(isnull(Credit,0)) - SUM(isnull(Debit,0))
                              FROM Transactions b 
                              WHERE b.TransactionID <= t.TransactionID  
                               and b.AccountID = t.AccountID),0)
                                 AS RunningTotal
FROM  Transactions t 
INNER JOIN dbo.BankAccounts ba ON t.AccountID = ba.AccountID

总计应为:(假设)起始余额:49.25

TransDate               Credit            Debit          RunningTotal      
----------------------- ----------------- -------------- ----------------- 
2011-10-08 20:14:00     NULL              12             37.25 
2011-10-08 20:14:00     2.11              NULL           39.36            
2011-10-07 20:14:00     42.25             NULL           81.61
2011-10-06 20:14:00     NULL              12.25          69.36
2011-10-05 20:14:00     31.25             NULL           100.61

--I would use the existing identity column to be 100% sure that I am dealing with the correct transaction.

SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, ba.AccountID,
        (isnull(t.Credit,0)-isnull(t.Debit,0))+COALESCE((SELECT SUM(isnull(Credit,0)) - SUM(isnull(Debit,0))
                              FROM Transactions b 
                              WHERE b.TransactionID < t.TransactionID 
                               and b.AccountID = t.AccountID),0)
                                 AS RunningTotal
FROM  Transactions t 
INNER JOIN dbo.BankAccounts ba ON t.AccountID = ba.AccountID

--also if you change the "Less Than" to "Less Than or Equal To", then you don't have to add the current item:

SELECT t.Created, t.Description, t.Credit, t.Debit, t.TransDate, t.TransactionID, ba.AccountID,
COALESCE((SELECT SUM(isnull(Credit,0)) - SUM(isnull(Debit,0))
                              FROM Transactions b 
                              WHERE b.TransactionID <= t.TransactionID  
                               and b.AccountID = t.AccountID),0)
                                 AS RunningTotal
FROM  Transactions t 
INNER JOIN dbo.BankAccounts ba ON t.AccountID = ba.AccountID

Totals should be : (Assuming) Starting Balance: 49.25

TransDate               Credit            Debit          RunningTotal      
----------------------- ----------------- -------------- ----------------- 
2011-10-08 20:14:00     NULL              12             37.25 
2011-10-08 20:14:00     2.11              NULL           39.36            
2011-10-07 20:14:00     42.25             NULL           81.61
2011-10-06 20:14:00     NULL              12.25          69.36
2011-10-05 20:14:00     31.25             NULL           100.61
洛阳烟雨空心柳 2024-12-15 14:15:51

如果这是Oracle,那么就有窗口函数。您可以使用 LEAD 和/或 LAG 对当前行相对于之前或即将到来的行执行计算(基于排序顺序)

if this is Oracle, then there are Window functions. you can use LEAD and/or LAG to perform calculations on the current row with respect to prior or upcoming rows (based on sort order)

谁把谁当真 2024-12-15 14:15:51

我正在尝试将这个逻辑与上面的 RowNumber 和 CTE 一起使用。在我的场景中,我需要计算两个字段的组合的运行总计:SalesProdLineID 和 FiscYerPer。这是我编码的内容(在本例中,由于基础表的大小,我将结果限制为单个月份:

 WITH RunningTotal AS
(
   SELECT to2PN.CompanyID, REPLACE(SP.SalesProdLineID, ' Sls PL','') AS SlsPL, vo2PNQtyProd.QtyProdStock,  FP.FiscYearPer, FP.FiscPer, FP.FiscYear
      , ROW_NUMBER() OVER (ORDER BY SP.SalesProdLineID,FP.FiscYearPer  ASC) AS RowNumber
      , ( ISNULL(vo2PNQtyProd.QtyProdStock, 0)  ) AS RunningTotal
   FROM to2PN  (NOLOCK)
 JOIN to2PNProdTempl   (NOLOCK)
     ON to2PN.PNKey = to2PNProdTempl.PNKey
JOIN timItem I  (NOLOCK)
    ON to2PNProdTempl.ItemKey = I.ItemKey
 JOIN timSalesProdLine SP (NOLOCK)
    ON I.SalesProdLineKey = SP.SalesProdLineKey
 JOIN vo2PNQtyProd   (NOLOCK)
     ON to2PNProdTempl.PNProdTemplKey=vo2PNQtyProd.PNProdTemplKey
 JOIN tglFiscalPeriod FP (NOLOCK)
    ON I.CompanyID = FP.CompanyID
        AND to2PN.ComplDateTime BETWEEN FP.StartDate AND Fp.EndDate
WHERE I.ItemID BETWEEN '0000-0' AND '1999-9'
    AND YEAR(to2PN.[ComplDateTime]) = '2018'    --  !! COMMENT OUT for final
    AND MONTH(to2PN.[ComplDateTime]) = 5    --  !! COMMENT OUT for final
)
SELECT t.CompanyID, t.SlsPL, t.QtyProdStock, t.FiscYearPer, t.FiscPer, t.FiscYear
   , ( SELECT SUM(tt.RunningTotal)
       FROM RunningTotal AS tt
       WHERE tt.RowNumber <= t.RowNumber) AS RunningTotal
FROM RunningTotal AS t
LEFT JOIN RunningTotal AS tt ON t.RowNumber = tt.RowNumber + 1
ORDER BY t.FiscYearPer DESC

问题是,一旦获得第一个 SalesProdLineID 的正确总计,它只是将运行总计添加到下一个销售产品线 ID。

I'm trying to use this logic with RowNumber and CTE from above. In my scenario, I need the Running Total to be calculated for a combination of two fields: SalesProdLineID and FiscYerPer. Here's what I have coded (in this example, due to the size of the underlying tables I restricted the results to a single Month:

 WITH RunningTotal AS
(
   SELECT to2PN.CompanyID, REPLACE(SP.SalesProdLineID, ' Sls PL','') AS SlsPL, vo2PNQtyProd.QtyProdStock,  FP.FiscYearPer, FP.FiscPer, FP.FiscYear
      , ROW_NUMBER() OVER (ORDER BY SP.SalesProdLineID,FP.FiscYearPer  ASC) AS RowNumber
      , ( ISNULL(vo2PNQtyProd.QtyProdStock, 0)  ) AS RunningTotal
   FROM to2PN  (NOLOCK)
 JOIN to2PNProdTempl   (NOLOCK)
     ON to2PN.PNKey = to2PNProdTempl.PNKey
JOIN timItem I  (NOLOCK)
    ON to2PNProdTempl.ItemKey = I.ItemKey
 JOIN timSalesProdLine SP (NOLOCK)
    ON I.SalesProdLineKey = SP.SalesProdLineKey
 JOIN vo2PNQtyProd   (NOLOCK)
     ON to2PNProdTempl.PNProdTemplKey=vo2PNQtyProd.PNProdTemplKey
 JOIN tglFiscalPeriod FP (NOLOCK)
    ON I.CompanyID = FP.CompanyID
        AND to2PN.ComplDateTime BETWEEN FP.StartDate AND Fp.EndDate
WHERE I.ItemID BETWEEN '0000-0' AND '1999-9'
    AND YEAR(to2PN.[ComplDateTime]) = '2018'    --  !! COMMENT OUT for final
    AND MONTH(to2PN.[ComplDateTime]) = 5    --  !! COMMENT OUT for final
)
SELECT t.CompanyID, t.SlsPL, t.QtyProdStock, t.FiscYearPer, t.FiscPer, t.FiscYear
   , ( SELECT SUM(tt.RunningTotal)
       FROM RunningTotal AS tt
       WHERE tt.RowNumber <= t.RowNumber) AS RunningTotal
FROM RunningTotal AS t
LEFT JOIN RunningTotal AS tt ON t.RowNumber = tt.RowNumber + 1
ORDER BY t.FiscYearPer DESC

The issue is that once it's got the correct total for the first SalesProdLineID, it simply adds that Running total to the next SalesProdLineID.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文