删除具有相同键的行

Alb*_* Y. 5 ssis rows

我有以下行的数据:

Name1  Name2  Name3  Col  
aaa    bbb    ccc    ...  
abc    ddd    ddd    1  
abc    ddd    ddd    2  
abc    ddd    ddd    3  
fff    fff    fff    ...  
ggg    ggg    hhh    4  
ggg    ggg    hhh    5  
Run Code Online (Sandbox Code Playgroud)

(Name1,Name2并且Name3是主键)

如何使用相同的3个主键从数据集中删除第一行?(留下设定的最后一行)

即上述结果将是:

Name1  Name2  Name3  Col  
aaa    bbb    ccc    ...  
abc    ddd    ddd    3  
fff    fff    fff    ...  
ggg    ggg    hhh    5  
Run Code Online (Sandbox Code Playgroud)

Edm*_*ppe 5

假设您的源数据顺序正确,并且您想要每组中的最后一条记录,则没有任何开箱即用的转换可以处理这种情况。然而,脚本转换可以相当容易地处理它。

这是一个示例数据流:

在此输入图像描述

为了简单起见,我使用FF_SRC_AllRowsFF_DST_SelectedRows作为平面文件源和目标(分别),使用您提供的示例数据;您的具体需求会有所不同。脚本转换SCR_SelectLastRow配置为转换(输入和输出):

在此输入图像描述

选择所有输入列(使用类型ReadOnly):

在此输入图像描述

创建一个输出(我将其命名为我的OutgoingRows,但您可以将其命名为任何您想要的名称),并将SynchronousInputID属性设置为None. 这将使您的脚本过滤掉您不需要的行。

在此输入图像描述

添加与输入列对应的输出列:

在此输入图像描述

并使用以下代码:

/* Microsoft SQL Server Integration Services Script Component
*  Write scripts using Microsoft Visual C# 2008.
*  ScriptMain is the entry point class of the script.*/

using System;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    class IncomingRowData
    {
        public string Name1;
        public string Name2;
        public string Name3;
        public string Col;
        public IncomingRowData(IncomingRowsBuffer Row)
        {
            Name1 = Row.Name1;
            Name2 = Row.Name2;
            Name3 = Row.Name3;
            Col = Row.Col;
        }
        public bool KeysDiffer(IncomingRowData other)
        {
            return (Name1 != other.Name1
                || Name2 != other.Name2
                || Name3 != other.Name3);
        }
        public void WriteToOutputBuffer(OutgoingRowsBuffer Row)
        {
            Row.AddRow();
            Row.Name1 = Name1;
            Row.Name2 = Name2;
            Row.Name3 = Name3;
            Row.Col = Col;
        }
    }

    private IncomingRowData _previousRow;

    public override void IncomingRows_ProcessInputRow(IncomingRowsBuffer Row)
    {
        if (_previousRow == null)
        {
            _previousRow = new IncomingRowData(Row);
        }
        IncomingRowData currentRow = new IncomingRowData(Row);
        if (currentRow.KeysDiffer(_previousRow))
        {
            _previousRow.WriteToOutputBuffer(this.OutgoingRowsBuffer);
        }
        _previousRow = currentRow;
    }

    public override void FinishOutputs()
    {
        if (_previousRow != null)
        {
            _previousRow.WriteToOutputBuffer(this.OutgoingRowsBuffer);
        }
        base.FinishOutputs();
    }
}
Run Code Online (Sandbox Code Playgroud)

这项技术的一个好处是,它允许您一次性处理数据,并且不需要使用临时表,也不需要将整个源数据集保留在内存中。根据您的数据集有多大,其中任何一个都可能会导致严重的性能问题。