Получить результат расчета из двух столбцов в SQL Server

Пожалуйста, обратитесь к этой таблице ниже.

 |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 |

как предоставить запрос для получения значения балансов? (Балансы = OrigAmt - AdjAmt (это правило только для первой строки), а затем во второй строке, Балансы = Предыдущие балансы (остатки в первой строке) - AdjAmt и т. Д.).

2 ответа

Решение

Вот один из способов использования оконной агрегатной функции

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
Другие вопросы по тегам