簡體   English   中英

如何通過計算SQL Server上的其他列減去列中的先前值

[英]How to subtract previous value in a column with calculation of other column on SQL server

我需要一張下表,如下所示。 如您所見, mgt_yeartot_dflt_mgtto_accum_mgt列。 在年份列中,其2016年的值為20 ,累計值為600 我想要的是當我做的時候

(to_accum_mgt - tot_dflt_mgt) 

我希望此計算結果在上一行中,如下表所示。 然后,此計算結果(即580 )用於減去2015年的9,例如(580-9) ,以此類推。 感謝@mathguy ,我已經在excel和Oracle中完成了此@mathguy ,但是如何在SQL Server中實現此結果。 我試圖使用此SQL Server,但無法正常工作。

請原諒我的英語和noob格式不正確。

我的桌子

line_seg    MGT_YEAR TOT_DFLT_MGT TOT_ACCUM_MGT
---------   -------- ------------ ------------
   A           2013           10   
   A           2014           15   
   A           2015            9   
   A           2016           20          600
   B           2013           10   
   B           2014           15   
   B           2015            8   
   B           2016           20          500

Oracle解決方案:

select mgt_year, tot_dflt_mgt,
       max(tot_accum_mgt) over () - 
         nvl( sum(tot_dflt_mgt) over 
                   (order by mgt_year 
                          rows between 1 following and unbounded following)
            , 0 ) as tot_accum_mgt
from t;    

但是我無法在SQL Server使用它。

所需的輸出

line_seg    MGT_YEAR TOT_DFLT_MGT TOT_ACCUM_MGT
---------   -------- ------------ ------------
   A           2013           10          556
   A           2014           15          471 
   A           2015            9          580
   A           2016           20          600
   B           2013           12          457
   B           2014           15          472
   B           2015            8          480
   B           2016           20          500
select *,
(sum(TOT_ACCUM_MGT) over()) -
(sum(TOT_DFLT_MGT ) over (order by TOT_DFLT_MGT )) as somecolname
from
table

放入Row_number()並將其與(a.ID = b.ID)和(a.row_num = b.row_num-1)上的上一行自行連接,或者可以使用lag()函數

請嘗試以下查詢。 我假設您使用的是SQL Server 2012+版本。 如果不是,請將FIRST_VALUE更改為SUM-

SELECT t1.line_seg, t1.mgt_year, t1.[tot_dflt_mgt]
, FIRST_VALUE(t1.tot_accum_mgt) OVER(PARTITION BY t1.[line_seg] ORDER BY t1.mgt_year DESC)
- ISNULL(SUM(t2.[tot_dflt_mgt]) OVER(PARTITION BY t2.[line_seg] ORDER BY t2.mgt_year DESC), 0) AS tot_accum_mgt
FROM [dbo].[t] AS t1
LEFT JOIN [dbo].[t] AS t2 ON (t2.line_seg = t1.line_seg AND t2.mgt_year = t1.mgt_year + 1)
ORDER BY t1.line_seg, t1.mgt_year ASC;

首先,我必須想象該表按日期的降序排序-

+------------+----------+--------------+---------------+
|  line_seg  | mgt_year | tot_dflt_mgt | tot_accum_mgt |
+------------+----------+--------------+---------------+
| A          |     2016 |           20 | 600           |
| A          |     2015 |            9 | NULL          |
| A          |     2014 |           15 | NULL          |
| A          |     2013 |           10 | NULL          |
| B          |     2016 |           20 | 500           |
| B          |     2015 |            8 | NULL          |
| B          |     2014 |           15 | NULL          |
| B          |     2013 |           12 | NULL          |
+------------+----------+--------------+---------------+

然后,我要做的就是從最近一年的tot_accum_mgt中減去之前tot_dflt_mgt總計 這等效於從tot_accum_mgt的當前計算值中減去先前的tot_dflt_mgt。要使用上一年的字段, 則將 LEFT JOIN用於自聯接表。 得出下表-

+------------+----------+--------------+---------------+------------+----------+--------------+---------------+
|  line_seg  | mgt_year | tot_dflt_mgt | tot_accum_mgt |  line_seg  | mgt_year | tot_dflt_mgt | tot_accum_mgt |
+------------+----------+--------------+---------------+------------+----------+--------------+---------------+
| A          |     2013 |           10 | NULL          | A          | 2014     | 15           | NULL          |
| A          |     2014 |           15 | NULL          | A          | 2015     | 9            | NULL          |
| A          |     2015 |            9 | NULL          | A          | 2016     | 20           | 600           |
| A          |     2016 |           20 | 600           | NULL       | NULL     | NULL         | NULL          |
| B          |     2013 |           12 | NULL          | B          | 2014     | 15           | NULL          |
| B          |     2014 |           15 | NULL          | B          | 2015     | 8            | NULL          |
| B          |     2015 |            8 | NULL          | B          | 2016     | 20           | 500           |
| B          |     2016 |           20 | 500           | NULL       | NULL     | NULL         | NULL          |
+------------+----------+--------------+---------------+------------+----------+--------------+---------------+

LEFT連接子句中的AND t2.mgt_year = t1.mgt_year + 1過濾器可完成獲取前一行值的技巧。 現在,我要做的就是計算前幾行(t2)的運行總計。 同樣,從任何東西中減去NULL將導致NULL 因此ISNULL用零代替任何NULL

ISNULL(SUM(t2.[tot_dflt_mgt]) OVER(PARTITION BY t2.[line_seg] ORDER BY t2.mgt_year DESC), 0) AS tot_accum_mgt

現在,由於我們擁有先前的tot_dflt_mgt總計,因此我們要做的就是刪除最新的(最大的mgt_yeartot_accum_mgt 我們通過使用FIRST_VALUE函數獲得該信息。 我猜也可以使用SUM。

FIRST_VALUE(t1.tot_accum_mgt) OVER(PARTITION BY t1.[line_seg] ORDER BY t1.mgt_year DESC)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM