如何将条件和聚合列添加到依赖于前面行的SQL查询?

时间:2017-04-18 08:40:55

标签: sql sql-server sql-server-2016

假设我有以下表格

|Id|Debtor|Creditor|
| 0|0     |400     |
| 1|1000  |0       |
| 2|2000  |0       |
| 3|0     |5000    |

我需要在每一行上添加两列TotalDebtTotalCredit,条件是在一行中只有一个总数被填充而另一个为零。 这是我正在寻找的查询结果。

|Id|Debtor|Creditor|TotalDebt|TotalCredit|
| 0|0     |400     |0        |400        |
| 1|1000  |0       |600      |0          |
| 2|2000  |0       |2600     |0          |
| 3|0     |5000    |0        |2400       |

5 个答案:

答案 0 :(得分:3)

这是一种方法:

创建并填充示例数据(在将来的问题中将此步骤保存为我们)

DECLARE @T AS TABLE
(
    id int,
    Debtor int,
    Creditor int
)

INSERT INTO @T VALUES
(0, 0   , 400 ),
(1, 1000, 0   ),
(2, 2000, 0   ),
(3, 0   , 5000)

使用cte获取Debtor和Creditor列的滚动总和:

;WITH CTE AS
(
    SELECT  id, 
            Debtor, 
            Creditor, 
            SUM(Creditor - Debtor) OVER(ORDER BY ID) As RollingSum
    FROM @T
)

从cte:

中选择
SELECT  Id,
        Debtor,
        Creditor,
        IIF(RollingSum < 0, -RollingSum, 0) As TotalDebt,
        IIF(RollingSum > 0, RollingSum, 0) As TotalCredit
FROM CTE

结果:

Id  Debtor  Creditor    TotalDebt   TotalCredit
0   0       400         0           400
1   1000    0           600         0
2   2000    0           2600        0
3   0       5000        0           2400

See a live demo on rextester.

答案 1 :(得分:2)

试试这个:

SELECT Id, Debtor, Creditor, 
       IIF(Debtor=0, 0, SUM(Debtor-Creditor) OVER (ORDER BY Id)) AS TotalDebt,
       IIF(Creditor=0, 0, SUM(Creditor-DEbtor) OVER (ORDER BY Id)) AS TotalCredit
FROM mytable

Demo here

答案 2 :(得分:0)

尝试:

SELECT *,
       case when [Debtor]> 0 then sum([Debtor] - [Creditor] ) over (order by id) 
            else 0 end as TotalDebt,
       case when [Creditor]> 0 then sum([Creditor] - [Debtor]) over (order by id) 
            else 0 end as TotalCredit
FROM table1

演示:http://rextester.com/HQCZQH39439

答案 3 :(得分:0)

使用子查询计算低于或等于给定“Id”的所有条目的总和

答案 4 :(得分:0)

如果你不想使用IIF(这是版本特定的),下面的查询将适用于你,尝试下面的查询这将给你确切的所需输出:

DECLARE @TableData AS TABLE(id int,Debtor int,Creditor int)

INSERT INTO @TableData VALUES
(0, 0, 400 ),
(1, 1000, 0),
(2, 2000, 0),
(3, 0, 5000),
(4, 10, 0),
(5, 0, 20)

;WITH SAMPLEDATA
AS
(
    SELECT *,0 TD,Creditor TC FROM @TableData WHERE ID=0
    UNION ALL
    SELECT T2.*,
    CASE WHEN T2.Debtor=0 THEN 0 ELSE T1.TD+(T2.Debtor-T1.Creditor) END,
    CASE WHEN T2.Creditor=0 THEN 0 ELSE T2.Creditor-T1.TD END
     FROM SAMPLEDATA T1 JOIN @TableData T2 ON T1.id=T2.id-1 
)
select * from SAMPLEDATA

查询输出,带有一些额外的虚拟数据:

---------------------------------
id  Debtor  Creditor    TD  TC
---------------------------------
0   0       400     0       400
1   1000    0       600     0
2   2000    0       2600    0
3   0       5000    0       2400
4   10      0       -4990   0
5   0       20      0       5010
---------------------------------