Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将条件和聚合列添加到依赖于前面行的SQL查询中?_Sql_Sql Server_Sql Server 2016 - Fatal编程技术网

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

如何将条件和聚合列添加到依赖于前面行的SQL查询中?,sql,sql-server,sql-server-2016,Sql,Sql Server,Sql Server 2016,假设我有下表 |Id|Debtor|Creditor| | 0|0 |400 | | 1|1000 |0 | | 2|2000 |0 | | 3|0 |5000 | 我需要在每一行上添加两列TotalDebt和TotalCredit,条件是在一行中只有一个总计被填充,另一个为零。 这是我要查找的查询结果 |Id|Debtor|Creditor|TotalDebt|TotalCredit| | 0|0 |400 |0

假设我有下表

|Id|Debtor|Creditor|
| 0|0     |400     |
| 1|1000  |0       |
| 2|2000  |0       |
| 3|0     |5000    |
我需要在每一行上添加两列
TotalDebt
TotalCredit
,条件是在一行中只有一个总计被填充,另一个为零。 这是我要查找的查询结果

|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       |
试试这个:

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

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

演示:

这里有一种方法:

创建并填充样本数据(请在以后的问题中保存此步骤)

将cte用于债务人和债权人列的滚动总和:

;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”的所有条目的总和

如果您不想使用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
---------------------------------

如果添加此行:
4100,0
?您的结果将在
TotalDebt
列中显示
-2300
,在
TotalCredit
列中显示
0
@ZoharPeled我认为这是OP真正想要的。好吧,总债务-2300实际上就是总信用2300,这就是我的建议所显示的。我想我们必须等待OP的回应。
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
---------------------------------