字符串聚集

问题描述

我的源表如下:

Account_Number,Code,Transaction_Amount,Comment,Sequence_Number
4321,W,10.21,1
4321,C,'Payment',2
4321,'From Checking Account',3
4321,D,20.00,4
4321,'Direct Deposit',4
7430,40.00,5
7430,'From Checking',5

来源是交易分类帐,W代表“提款”,D代表“存款”,C代表评论。当每笔交易发生时,都可以跟进。 0条或更多注释行。 我想汇总“ W”或“ D”之后的所有注释,并将它们添加到“ W”或“ D”行。示例:

Account_Number,'Payment,From Checking Account',"From Checking,5

解决方法

我认为这是一个“空白与岛”的问题,您想在此问题中收集所有注释,并将它们带到上一个岛。

SQL Server没有用于字符串聚合的窗口函数,这使事情有些棘手。这可能是带有横向联接的更简单的地址:

select t.account_number,t.code,t.transaction_amount,c.comment,t.sequence_number
from mytable t
outer apply (
    select top (1) t1.sequence_number as next_sequence_number
    from mytable t1
    where 
        t1.account_number = t.account_number 
        and t1.sequence_number > t.sequence_number
        and t1.code <> 'C' 
    order by t1.sequence_number
) s
outer apply (
    select string_agg(t1.comment) within group(order by t1.sequence_number) comment
    from mytable t1
    where
        t1.account_number = t.account_number 
        and t1.sequence_number > t.sequence_number
        and (
            t1.sequence_number < s.next_sequence_number 
            or s.next_sequence_number is null
        )
        and t1.code = 'C' 
) c
where t.code <> 'C'

第一个横向连接计算“下一个”非注释事务的序列号;第二个汇总了当前行和下一行之间的所有注释。

请注意,string_agg()仅从SQL Server 2017开始可用。

,

这是使用LEADSTRING_AGG的查询。假设Withdraw的最后DepositAccount_Number行的某个大数字。

HERE是工作代码。

SELECT *,(
        SELECT STRING_AGG(comm.Comment,',') Comment
        FROM Transactions comm
        WHERE comm.Account_Number = a.Account_Number
            AND comm.Code = 'C'
            AND comm.Sequence_Number >= a.Sequence_Number
            AND comm.Sequence_Number < a.END_Sequence_Number
        )
FROM (
    SELECT *,ISNULL(LEAD(Sequence_Number) OVER (
                PARTITION BY Account_Number ORDER BY Sequence_Number
                ),100000000) END_Sequence_Number
    FROM dbo.Transactions t
    WHERE Code IN ('W','D')
    ) a

结果: enter image description here

,

我会使用string_agg()来做到这一点,但要为每行分配组。有哪些小组?非C代码的累积数量。所以:

select account,max(case when code <> 'C' then code end) as code,sum(amount) as amount,string_agg(comment,') within group (order by seq) as comments
from (select t.*,sum(case when code <> 'C' then 1 else 0 end) over (partition by account order by sequence) as grp
      from t
     ) t
group by account,grp;

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...