规范化CSV文件数据

时间:2014-09-15 19:15:38

标签: sql sql-server csv ssis normalization

所以我有一个格式如下的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进行规范化。

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

这不是不可能在SO上展示的。 ;)

enter image description here

源数据是CSV的内在特殊性。你只有数据。我将使用源查询模拟它并添加额外的返回以确保我已经解决了N个返回的问题。

您正在查看多播运营商。这允许您对同一组数据执行操作,因此我们将有N个数据流出来。这不会复制数据,只是允许不同的操作员对其进行处理。

我们这里有两个流。一个用于聚合(用于生成ReturnID和Employee的唯一组合),另一个用于详细数据(ReturnID,ProductID和Quantity)。

我对数据使用聚合转换,并对ReturnIDEmployee使用GroupBy操作。

我假设详细数据已经处于正确的粒度级别,但如果可以进一步汇总,则在其中添加聚合操作,GroupBy返回ReturnID和ProductID以及SUM数量。

BIML

商业智能标记语言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;