我的数据包含以下行:
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
(Name1
,Name2
和Name3
是主键)
如何使用相同的3个主键从数据集中删除第一行? (只留下 集合的最后一行)
即。以上结果将是:
Name1 Name2 Name3 Col
aaa bbb ccc ...
abc ddd ddd 3
fff fff fff ...
ggg ggg hhh 5
答案 0 :(得分:4)
假设您的源数据的顺序正确,并且您希望每个集合中的 last 记录,则没有任何可以处理这种情况的开箱即用转换。但是,脚本转换可以很容易地处理它。
以下是数据流示例:
为了简单起见,我使用FF_SRC_AllRows
和FF_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();
}
}
这项技术的一个好处是它允许您在一次传递中处理数据,既不需要使用登台表也不需要将整个源数据集保存在内存中。根据您的数据集的大小,其中任何一个都可能导致严重的性能问题。
答案 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:
数据:
聚合元素:
结果:
如果使用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 |