删除具有相同键的行

时间:2013-03-04 00:36:55

标签: 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  

Name1Name2Name3是主键)

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

即。以上结果将是:

Name1  Name2  Name3  Col  
aaa    bbb    ccc    ...  
abc    ddd    ddd    3  
fff    fff    fff    ...  
ggg    ggg    hhh    5  

4 个答案:

答案 0 :(得分:4)

假设您的源数据的顺序正确,并且您希望每个集合中的 last 记录,则没有任何可以处理这种情况的开箱即用转换。但是,脚本转换可以很容易地处理它。

以下是数据流示例:

enter image description here

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

enter image description here

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

enter image description here

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

enter image description here

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

enter image description here

并沿着这些方向使用代码:

/* 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();
    }
}

这项技术的一个好处是它允许您在一次传递中处理数据,既不需要使用登台表也不需要将整个源数据集保存在内存中。根据您的数据集的大小,其中任何一个都可能导致严重的性能问题。

答案 1 :(得分:1)

建议#1:如果可能的话,请在源查询中执行此操作。

假设无法实现,假设您始终希望选择Col的最大值,则可以在数据流中使用Aggregate组件。

只需将所有列添加到聚合输入中,对于操作,为Name1,Name2和Name3选择“Group By”,为Col。选择“Maximum”。

不幸的是,聚合组件是一个异步组件 - 这意味着当数据流入它时,整个流程将暂停,因为在每行读取之前,它不会知道每个组的“最大”值。

答案 2 :(得分:1)

SELECT name1, 
       name2, 
       name3, 
       col 
FROM   (SELECT name1, 
               name2, 
               name3, 
               col, 
               Max(rn) 
                 over ( 
                   PARTITION BY name1, name2, name3 ) AS max_rn, 
               rn 
        FROM   (SELECT name1, 
                       name2, 
                       name3, 
                       col, 
                       Row_number() 
                         over ( 
                           PARTITION BY name1, name2, name3 
                           ORDER BY col ) AS rn 
                FROM   test1)) 
WHERE  max_rn = rn; 

您可以尝试使用test1为tablename

的地方

答案 3 :(得分:1)

您需要对数据进行分组并选择max Col值。

FLOW:

enter image description here

数据:

enter image description here

聚合元素:

enter image description here

结果: enter image description here

如果使用SQL Table并且可以编写查询:

<强> SQLFIDDLEExample

SELECT Name1, Name2, Name3, MAX(Col) Col
FROM Table1
GROUP BY Name1, Name2, Name3

结果:

| NAME1 | NAME2 | NAME3 | COL |
-------------------------------
|   aaa |   bbb |   ccc | ... |
|   abc |   ddd |   ddd |   3 |
|   fff |   fff |   fff | ... |
|   ggg |   ggg |   hhh |   5 |