我正在尝试在SQL Server 2008的View中运行总计
这是我的表格
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
我真的很接近......就在当天有2笔交易时,它没有正确计算出来..有什么想法吗?
答案 0 :(得分:6)
自2008年以来,我使用了ROW_NUMBER
和CTE
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
答案 1 :(得分:1)
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
答案 2 :(得分:1)
- 我会使用现有的标识栏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
答案 3 :(得分:0)
如果这是Oracle,则有Window函数。您可以使用LEAD和/或LAG相对于先前或即将进行的行(基于排序顺序)对当前行执行计算
答案 4 :(得分:0)
我试图从上方将这种逻辑与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的正确总计,它就会将该运行总计添加到下一个SalesProdLineID。