从 sql 服务器中的两列获取计算结果
get calculation result from two columns in sql server
请参考下面这个table。
|RefNbr | DocDate | OrigAmt | AdjAmt | Balances |
|INV001 | 2016-03-15 | 5,000.00 | 250.00 | 4,750.00 |
|INV002 | 2016-03-16 | 5,000.00 | 750.00 | 4,000.00 |
|INV003 | 2016-03-17 | 5,000.00 | 1,000.00 | 3,000.00 |
|INV004 | 2016-03-19 | 5,000.00 | 500.00 | 2,500.00 |
如何提供查询以获取余额值?
(Balances = OrigAmt - AdjAmt(此规则仅适用于第一行),然后在第二行中,Balances = Prev Balances(第一行中的余额)- AdjAmt,等等)。
这是使用窗口聚合函数的一种方法
select OrigAmt - sum(AdjAmt) over(order by DocDate asc) as Balances
From yourtable
对于小于 sql server 2012 的任何东西,使用这个
SELECT OrigAmt - cum_sum AS Balances
FROM yourtable a
CROSS apply (SELECT Sum(AdjAmt)
FROM yourtable b
WHERE b.DocDate <= a.DocDate) cs( cum_sum)
试试下面的代码,它可能对你帮助不大。
**
CREATE TABLE #TAB(REFNBR VARCHAR(MAX),DOCDATE DATETIME ,ORIGAMT DECIMAL(18,2),ADJAMT DECIMAL(18,2))
INSERT INTO #TAB VALUES ('INV001','2016-03-15',5000.00,250.00),('INV002','2016-03-16',5000.00,750.00),
('INV003','2016-03-17',5000.00,1000.00),('INV004','2016-03-19',5000.00,500.00)
;WITH CTE AS (
SELECT REFNBR,
DOCDATE,
ORIGAMT,
ADJAMT,
ORIGAMT-ADJAMT AS BALANCE,
ROW_NUMBER() OVER ( ORDER BY DOCDATE) AS RN
FROM #TAB)
SELECT a.REFNBR,
a.DOCDATE,
a.ORIGAMT,
a.ADJAMT,
CASE WHEN ISNULL(LAG(a.BALANCE + ISNULL(x.ADDS,0)) OVER (ORDER BY a.RN),0) + a.ORIGAMT - a.ADJAMT < 0
THEN 0
ELSE a.BALANCE + ISNULL(x.ADDS,0)
END AS FINAL_BALANCE
FROM CTE a
CROSS APPLY (SELECT SUM(BALANCE) AS ADDS
FROM CTE f
WHERE f.REFNBR = a.REFNBR AND f.RN < a.RN
) x
**
以上代码适用于2014年,2014年以下请尝试以下代码一次
SELECT REFNBR,
DocDate,
OrigAmt,
AdjAmt,
CASE
WHEN RNO > 1 THEN Sum(OrigAmt - ADJAMT)
OVER(
PARTITION BY REFNBR
ORDER BY RNO)
ELSE Iif(( OrigAmt - ADJAMT ) < 0, 0, OrigAmt - ADJAMT)
END
FROM (SELECT *,
Row_number()
OVER(
PARTITION BY REFNBR
ORDER BY DocDate) AS RNO
FROM #TAB) A
请参考下面这个table。
|RefNbr | DocDate | OrigAmt | AdjAmt | Balances |
|INV001 | 2016-03-15 | 5,000.00 | 250.00 | 4,750.00 |
|INV002 | 2016-03-16 | 5,000.00 | 750.00 | 4,000.00 |
|INV003 | 2016-03-17 | 5,000.00 | 1,000.00 | 3,000.00 |
|INV004 | 2016-03-19 | 5,000.00 | 500.00 | 2,500.00 |
如何提供查询以获取余额值? (Balances = OrigAmt - AdjAmt(此规则仅适用于第一行),然后在第二行中,Balances = Prev Balances(第一行中的余额)- AdjAmt,等等)。
这是使用窗口聚合函数的一种方法
select OrigAmt - sum(AdjAmt) over(order by DocDate asc) as Balances
From yourtable
对于小于 sql server 2012 的任何东西,使用这个
SELECT OrigAmt - cum_sum AS Balances
FROM yourtable a
CROSS apply (SELECT Sum(AdjAmt)
FROM yourtable b
WHERE b.DocDate <= a.DocDate) cs( cum_sum)
试试下面的代码,它可能对你帮助不大。
**
CREATE TABLE #TAB(REFNBR VARCHAR(MAX),DOCDATE DATETIME ,ORIGAMT DECIMAL(18,2),ADJAMT DECIMAL(18,2))
INSERT INTO #TAB VALUES ('INV001','2016-03-15',5000.00,250.00),('INV002','2016-03-16',5000.00,750.00),
('INV003','2016-03-17',5000.00,1000.00),('INV004','2016-03-19',5000.00,500.00)
;WITH CTE AS (
SELECT REFNBR,
DOCDATE,
ORIGAMT,
ADJAMT,
ORIGAMT-ADJAMT AS BALANCE,
ROW_NUMBER() OVER ( ORDER BY DOCDATE) AS RN
FROM #TAB)
SELECT a.REFNBR,
a.DOCDATE,
a.ORIGAMT,
a.ADJAMT,
CASE WHEN ISNULL(LAG(a.BALANCE + ISNULL(x.ADDS,0)) OVER (ORDER BY a.RN),0) + a.ORIGAMT - a.ADJAMT < 0
THEN 0
ELSE a.BALANCE + ISNULL(x.ADDS,0)
END AS FINAL_BALANCE
FROM CTE a
CROSS APPLY (SELECT SUM(BALANCE) AS ADDS
FROM CTE f
WHERE f.REFNBR = a.REFNBR AND f.RN < a.RN
) x
**
以上代码适用于2014年,2014年以下请尝试以下代码一次
SELECT REFNBR,
DocDate,
OrigAmt,
AdjAmt,
CASE
WHEN RNO > 1 THEN Sum(OrigAmt - ADJAMT)
OVER(
PARTITION BY REFNBR
ORDER BY RNO)
ELSE Iif(( OrigAmt - ADJAMT ) < 0, 0, OrigAmt - ADJAMT)
END
FROM (SELECT *,
Row_number()
OVER(
PARTITION BY REFNBR
ORDER BY DocDate) AS RNO
FROM #TAB) A