【问题标题】:Normalizing CSV file data标准化 CSV 文件数据
【发布时间】:2014-11-09 09:44:09
【问题描述】:

所以我有一个格式如下的 CSV 文件:

ReturnID|Employee|CreateDate|ProductID|Quantity
100|EMP1|2014-09-15|20|500
100|EMP1|2014-09-15|21|30

ReturnID 标识退货,ProductID 标识与退货关联的产品。

我需要对 CSV 文件中的数据进行规范化,并以这种形式导入数据:

包含以下字段的单个返回记录:
返回ID|员工
100|员工1

与退货记录关联的两个产品记录。 这两条记录看起来像这样:

ReturnID|ProductID|数量
100|20|500
100|21|30

我计划使用 SSIS 导入 CSV 文件,但我想使用 SQL Server 进行规范化。

感谢您的帮助。

【问题讨论】:

  • 所以您的要求与 CSV 无关?
  • 我们收到一个 CSV 文件,需要按照我描述的方式导入数据库。
  • 为什么不导入一个导入表并通过脚本从这个表中规范化?
  • 那也可以,我只是不确定允许我执行此操作的 SQL。
  • 您想在 SSIS 数据流中还是在它到达数据库之后进行转换?无论如何它与 CSV 无关

标签: sql sql-server csv ssis normalization


【解决方案1】:

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

源数据本质上是 CSV 并没有什么特别之处。你只有数据。我将使用源查询对其进行模拟,并添加一个额外的返回,以确保我已经解决了 N 个返回的问题。

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

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

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

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

比米尔

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

【讨论】:

    【解决方案2】:

    假设您设法将数据导入“MyImport”表。

    您需要做的就是使用 DISTINCT:

    SELECT DISTINCT ReturnID, Employee FROM MyImport;
    SELECT DISTINCT ReturnID, ProductID, Quantity FROM MyImport;
    

    【讨论】:

      猜你喜欢
      • 2012-08-07
      • 2014-03-22
      • 2013-09-09
      • 1970-01-01
      • 2015-06-14
      • 2017-01-20
      • 1970-01-01
      • 2018-05-19
      相关资源
      最近更新 更多