所以我有一个格式如下的CSV文件:
ReturnID |员工| CREATEDATE |的ProductID |数量
100个| EMP1 | 2014年9月15日| 20个| 500个
100 | EMP1 | 2014年9月15日| 21 | 30个
ReturnID标识退货,ProductID标识与退货相关联的产品。
我需要规范化CSV文件中的数据并以此格式导入数据:
包含字段的单个返回记录:
ReturnID |员工
100 | EMP1
和
与退货记录关联的两个产品记录。 这两个记录看起来像这样:
ReturnID |的ProductID |数量
100个| 20个| 500个
100 | 21 | 30
我打算使用SSIS导入CSV文件,但我想使用SQL Server进行规范化。
感谢您的帮助。
答案 0 :(得分:2)
这不是不可能在SO上展示的。 ;)
源数据是CSV的内在特殊性。你只有数据。我将使用源查询模拟它并添加额外的返回以确保我已经解决了N个返回的问题。
您正在查看多播运营商。这允许您对同一组数据执行操作,因此我们将有N个数据流出来。这不会复制数据,只是允许不同的操作员对其进行处理。
我们这里有两个流。一个用于聚合(用于生成ReturnID和Employee的唯一组合),另一个用于详细数据(ReturnID,ProductID和Quantity)。
我对数据使用聚合转换,并对ReturnID
和Employee
使用GroupBy操作。
我假设详细数据已经处于正确的粒度级别,但如果可以进一步汇总,则在其中添加聚合操作,GroupBy返回ReturnID和ProductID以及SUM数量。
商业智能标记语言Biml描述了商业智能平台。在这里,我们将用它来描述ETL。 BIDS Helper,是Visual Studio / BIDS / SSDT的免费补充,它解决了许多缺点。具体来说,我们将使用将描述ETL的Biml文件转换为SSIS包的能力。这样做的另一个好处是为您提供了一种机制,使您能够准确生成我正在描述的解决方案,而不是点击许多繁琐的对话框。
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<!-- 74383 -->
<Connections>
<OleDbConnection ConnectionString="Provider=SQLNCLI11;Data Source=localhost\dev2014;Integrated Security=SSPI;Initial Catalog=tempdb" Name="CM_OLE" />
</Connections>
<Packages>
<Package Name="so_25855263" ConstraintMode="Linear">
<Tasks>
<Dataflow Name="DFT Make Data">
<Transformations>
<OleDbSource ConnectionName="CM_OLE" Name="OLE_SRC Gen data">
<DirectInput>SELECT
D.*
FROM
(
VALUES
(100,'EMP1','2014-09-15',20,500)
, (100,'EMP1','2014-09-15',21,30)
, (200,'EMP2','2014-09-25',20,10)
, (200,'EMP2','2014-09-25',21,20)
, (200,'EMP2','2014-09-25',22,30)
, (200,'EMP2','2014-09-25',23,40)
) D(ReturnID,Employee,CreateDate,ProductID,Quantity);</DirectInput>
</OleDbSource>
<!--
Multicast our data
-->
<Multicast Name="MC Create alternate paths">
<OutputPaths>
<OutputPath Name="AggregatePath">
</OutputPath>
<OutputPath Name="Default">
</OutputPath>
</OutputPaths>
</Multicast>
<!--
Handle aggregating the data based on ReturnID and Employee
-->
<Aggregate Name="AGG ReturnID and Employee" >
<InputPath OutputPathName="MC Create alternate paths.AggregatePath" />
<OutputPaths>
<OutputPath Name="AGG Out">
<Columns>
<Column SourceColumn="ReturnID" TargetColumn="ReturnID" Operation="GroupBy"/>
<Column SourceColumn="Employee" TargetColumn="Employee" Operation="GroupBy"/>
</Columns>
</OutputPath>
</OutputPaths>
</Aggregate>
<!--
Do something with the aggregated data.
-->
<DerivedColumns Name="DER bitbucket Aggregate">
<InputPath OutputPathName="AGG ReturnID and Employee.AGG Out"/>
</DerivedColumns>
<!--
Do something with the other "half" of the data
I assume it is already aggregated at the ReturnID|ProductID|Quantity level.
If this is incorrect, patch in another aggregate
-->
<DerivedColumns Name="DER bitbucket default">
<InputPath OutputPathName="MC Create alternate paths.Default" />
</DerivedColumns>
</Transformations>
</Dataflow>
</Tasks>
</Package>
</Packages>
</Biml>
答案 1 :(得分:0)
让我们假设您设法将数据提供给“MyImport”表。
您需要做的就是使用DISTINCT:
SELECT DISTINCT ReturnID, Employee FROM MyImport;
SELECT DISTINCT ReturnID, ProductID, Quantity FROM MyImport;