在SSIS中将多行合并为一行

时间:2018-01-24 08:20:58

标签: sql-server ssis etl

我目前有一个包含4列的平面文件:GateNumber,Status,DateTime和Priority。当状态编号为1时,门打开。状态编号2关闭门。该文件如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum PlayerState
{
    Idle,
    Walking,
    Sprinting,
    CrouchedIdle,
    CrouchedWalking
};

public class Player : MonoBehaviour
{
    public PlayerState playerState;

    // Use this for initialization
    void Start()
    {
        playerState = PlayerState.Idle;
    }

    // Update is called once per frame
    void Update()
    {
        UpdatePlayerState();
    }

    //Detects input from player and switches player state accordingly
    void UpdatePlayerState()
    {
        if (playerState == PlayerState.Idle)
        {
            if (Input.GetAxis("Horizontal") > 0 || Input.GetAxis("Horizontal") < 0 ||
                Input.GetAxis("Vertical") > 0 || Input.GetAxis("Vertical") < 0)
            {
                playerState = PlayerState.Walking;
            }
            if (Input.GetAxis("Vertical") > 0 && Input.GetButtonDown("Sprint"))
            {
                playerState = PlayerState.Sprinting;
            }
            if(Input.GetButtonDown("Crouch"))
            {
                playerState = PlayerState.CrouchedIdle;
            }
        }
        if (playerState == PlayerState.Walking)
        {
            if (Input.GetAxis("Vertical") > 0 && Input.GetButtonDown("Sprint"))
            {
                playerState = PlayerState.Sprinting;
            }
            if (Input.GetAxis("Horizontal") == 0 && Input.GetAxis("Vertical") == 0)
            {
                playerState = PlayerState.Idle;
            }
        }
        if (playerState == PlayerState.Sprinting)
        {
            if (Input.GetAxis("Horizontal") == 0 && Input.GetAxis("Vertical") == 0)
            {
                playerState = PlayerState.Idle;
            }
            if(!Input.GetButton("Sprint") || Input.GetAxis("Horizontal") > 0 || Input.GetAxis("Horizontal") < 0)
            {
                playerState = PlayerState.Walking;
            }
        }
        if(playerState == PlayerState.CrouchedIdle)
        {
            if (Input.GetAxis("Horizontal") > 0 || Input.GetAxis("Horizontal") < 0 ||
                Input.GetAxis("Vertical") > 0 || Input.GetAxis("Vertical") < 0)
            {
                playerState = PlayerState.CrouchedWalking;
            }
            if(Input.GetButtonDown("Crouch"))
            {
                playerState = PlayerState.Idle; //If I comment this line out I can crouch normally but can't stand up, however if I leave this line in I can't crouch at all.
            }
            if(Input.GetAxis("Vertical") > 0 && Input.GetButtonDown("Sprint"))
            {
                playerState = PlayerState.Sprinting;
            }
        }
        if(playerState == PlayerState.CrouchedWalking)
        {
            if(Input.GetButtonDown("Crouch"))
            {
                playerState = PlayerState.Walking;
            }
            if (Input.GetAxis("Vertical") > 0 && Input.GetButtonDown("Sprint"))
            {
                playerState = PlayerState.Sprinting;
            }
            if (Input.GetAxis("Horizontal") == 0 && Input.GetAxis("Vertical") == 0)
            {
                playerState = PlayerState.CrouchedIdle;
            }
        }
    }
}

有没有办法在SSIS的数据流中将这些行组合成一个?最终结果将是这样的:

| GateNumber | Status | DateTime          | Priority
---------------------------------------------------------
| 53         | 1    | 2017-07-23 16:00:00 | 2
| 53         | 2    | 2017-07-23 16:01:30 | 2
| 87         | 1    | 2017-07-23 16:03:30 | 3
| 113        | 1    | 2017-07-23 16:04:40 | 2
| 113        | 2    | 2017-07-23 16:05:30 | 2
| 87         | 2    | 2017-07-23 16:07:30 | 3
| 53         | 1    | 2017-07-23 16:09:00 | 2
| 53         | 2    | 2017-07-23 16:09:30 | 2

2 个答案:

答案 0 :(得分:2)

这是关于识别正确的开始和结束的方法。令我感到惊讶的是,您的来源中没有比门号更好的标识符。如果gatenumber是唯一且不重复的话,我会使用聚合对象并选择datetime的max和min作为开始和结束。

建议的解决方案:

步骤1:使用任何源类型

加载源数据

步骤2:根据gatenumber和DateTime对数据进行排序。

这将使您的行按顺序排列,以便它具有1:2 1:2序列

步骤3:添加脚本组件(转换)

第4步:创建符合您需求的新输出。我称之为&#34; new&#34;

步骤5:检查所有列是否为只读

第6步:以下代码

public DateTime starttime;

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    if (Row.Status == 1)
        starttime = Row.DateTime;
    else
    {
        newBuffer.AddRow();
        newBuffer.GN = Row.GateNumber;
        newBuffer.Start = starttime;
        newBuffer.End = Row.DateTime;
        newBuffer.priority = Row.Priority;
    }


}

注意:公共DateTime starttime在RowProcessing之外声明。

步骤7:选择正确的输出并继续

答案 1 :(得分:0)

使用row_number()函数指定排名并按GateNumberand row_numbers对其进行分组

select a.GateNumber,
       min(case when a.status = 1 then a.Datetime end)  StartDtm,
       max(case when a.status = 2 then a.Datetime end) EndDtm,
       max(Priority) Priority from
  (
    select *, 
          row_number() over (partition by GateNumber, Status order by Datetime) rn 
    from table
  )a 
group by a.GateNumber, a.rn

注意:这假设您在状态1,2

对中始终具有GateNumber