如何获取此查询中的实际运行余额

时间:2016-03-02 08:17:06

标签: sql sql-server-2014

继昨天我最初问过的问题(here)之后,我能够构建以下sql查询,该查询生成了一份运行的发票和付款清单。

SELECT 
    'Invoice' AS TransactionType, 
    i.InvoiceNumber AS Description, 
    i.InvoiceDate AS TransactionDate, 
    CAST(ROUND(i.OutstandingBalance, 2) AS DECIMAL(12, 2)) AS TransactionAmount  
FROM 
    Invoices i
WHERE 
    i.CustomerId = 12 
    AND i.InvoiceDate BETWEEN '20150601' AND '20160229' 
    AND i.OutstandingBalance > 0.02

UNION

SELECT 
    'Payment' AS TransactionType, 
    ip.InvoicePaymentId AS Description, 
    ip.InvoicePaymentDate AS TransactionDate,
    - ip.Amount AS TransactionAmount  
FROM 
    InvoicePayments ip
WHERE 
    ip.CustomerId = 12 
    AND ip.InvoicePaymentDate BETWEEN '20150601' AND '20160229'
ORDER BY 
    TransactionDate

我现在要做的是生成一个额外的列,该列实际上是帐户的运行余额。我想如果我开始使用变量,那么应该可以添加(或减去它以给我我想要的东西)。为此我尝试了以下内容;

DECLARE @OutstandingBalance MONEY = 0

SELECT 
    'Invoice' AS TransactionType, i.InvoiceNumber AS Description, 
    i.InvoiceDate AS TransactionDate, 
    CAST(ROUND(i.OutstandingBalance, 2) AS DECIMAL(12, 2)) AS TransactionAmount,
    @OutstandingBalance + CAST(ROUND(i.OutstandingBalance, 2) AS DECIMAL(12, 2)) AS Balance 
FROM 
    Invoices i
WHERE 
    i.CustomerId = 12 
    AND i.InvoiceDate  BETWEEN '20150601' AND '20160229' 
    AND i.OutstandingBalance > 0.02

其中产生了以下结果。

enter image description here

然而,尝试通过使@OutstandingBalance + =像这样修改查询;

DECLARE @OutstandingBalance MONEY = 0

SELECT
    'Invoice' AS TransactionType, i.InvoiceNumber AS Description, 
    i.InvoiceDate AS TransactionDate, 
    CAST(ROUND(i.OutstandingBalance, 2) AS DECIMAL(12, 2)) AS TransactionAmount,
    @OutstandingBalance += CAST(ROUND(i.OutstandingBalance, 2)AS DECIMAL(12,2)) AS Balance 
FROM 
    Invoices i
WHERE 
    i.CustomerId = 12 
    AND i.InvoiceDate  BETWEEN '20150601' AND '20160229' 
    AND i.OutstandingBalance > 0.02

错误地告诉我关键字AS附近的语法不正确(我认为是AS平衡。我怀疑我应该'设置'@OutstandingBalance的值但是在其中添加一个set语句选择也会引发错误。

是否可以在此类查询中创建运行余额?若然,如何设置@OutstandingBalance来实现它呢?

在回答下面的答案时,这是我得到的结果集:

enter image description here

EDIT 修改后的查询以同时支付发票和付款:

   SELECT 'Invoice' AS TransactionType, 
       i.InvoiceNumber AS Description, 
       i.InvoiceDate AS TransactionDate, 
       CAST(ROUND(i.OutstandingBalance,2)AS DECIMAL(12,2)) AS TransactionAmount , 
       SUM(CAST(ROUND(i.OutstandingBalance,2)AS DECIMAL(12,2))) OVER(ORDER BY i.InvoiceDate, i.InvoiceNumber) AS Balance 
FROM Invoices i
WHERE i.CustomerId = 12 
AND i.InvoiceDate  BETWEEN '20150601' AND '20160229' 
AND i.OutstandingBalance > 0.02

UNION

  SELECT 
    'Payment' AS TransactionType, 
    ip.InvoicePaymentId AS Description, 
    ip.InvoicePaymentDate AS TransactionDate,
    - ip.Amount AS TransactionAmount,
    SUM(CAST(ROUND(-ip.Amount,2) AS DECIMAL(12,2))) OVER(ORDER BY ip.InvoicePaymentDate,ip.InvoicePaymentId) AS Balance  

    FROM InvoicePayments ip
  WHERE ip.CustomerId = 12 
  AND ip.InvoicePaymentDate  BETWEEN '20150601' AND '20160229'



ORDER BY TransactionDate, Description

产生以下内容:

enter image description here

1 个答案:

答案 0 :(得分:2)

您可以将SUMOVER子句一起使用,如下所示:

SELECT 'Invoice' AS TransactionType, 
       i.InvoiceNumber AS Description, 
       i.InvoiceDate AS TransactionDate, 
       CAST(ROUND(i.OutstandingBalance,2)AS DECIMAL(12,2)) AS TransactionAmount , 
       SUM(CAST(ROUND(i.OutstandingBalance,2)AS DECIMAL(12,2))) OVER(ORDER BY i.InvoiceDate, i.InvoiceNumber) AS Balance 
FROM Invoices i
WHERE i.CustomerId = 12 
AND i.InvoiceDate  BETWEEN '20150601' AND '20160229' 
AND i.OutstandingBalance > 0.02
ORDER BY TransactionDate, Description

您也可以使用cte保存一个演员:

;WITH cte AS
(
SELECT 'Invoice' AS TransactionType, 
       i.InvoiceNumber AS Description, 
       i.InvoiceDate AS TransactionDate, 
       CAST(ROUND(i.OutstandingBalance,2)AS DECIMAL(12,2)) AS TransactionAmount
FROM Invoices i
WHERE i.CustomerId = 12 
AND i.InvoiceDate  BETWEEN '20150601' AND '20160229' 
AND i.OutstandingBalance > 0.02
)

SELECT TransactionType, 
       Description,
       TransactionDate,
       TransactionAmount,
       SUM(TransactionAmount) OVER(ORDER BY TransactionDate, Description) AS Balance 
FROM cte
ORDER BY TransactionDate, Description