计算Azure Data Lake Analytics U-SQL作业中的时间差异

时间:2017-05-21 09:48:27

标签: azure-data-lake u-sql

在我们的项目中,我们必须根据收到的输入数据定期计算聚合和进一步的计算。

一个常见的要求是计算输入数据流中某些行之间的时差。

例如,这是我的输入数据流:

时间戳事件值
2017-05-21 11:33 e1 17
2017-05-21 11:37 e2 18
2017-05-21 11:38 e3 18
2017-05-21 11:39 e1 19
2017-05-21 11:42 e2 19

我现在想要计算e2事件和最后收到的e1事件之间的所有时间跨度(按时间戳排序)。

我希望结果如下: 3分钟) 4分钟(分钟)

类似的要求是计算相同类型事件之间的时间跨度(即e1事件之间的所有差异),我期望这个结果: 6分钟(分钟)

到目前为止我的尝试:

使用LAG函数和WHEN子句可以很容易地实现这种分析,但遗憾的是U-SQL中缺少WHEN子句。 如果它是T-SQL,也可以使用语句的SELECT-Clause中的Sub-Selects来解决这个问题,但不幸的是,这在U-SQL中也是不可能的。

您对如何解决此问题有任何建议或示例脚本吗? 非常感谢你的帮助!

2 个答案:

答案 0 :(得分:1)

在U-SQL中,您可以使用c#方法进行简单的日期算术。如果您的数据与您描述的一样简单,您可以只对e1和e2事件进行排名然后加入它们,如下所示:

@data =
    EXTRACT Timestamp DateTime,
            Event string,
            Value int
    FROM "/input/input58.csv"
    USING Extractors.Csv();

//@data = SELECT *
//     FROM (
//        VALUES
//        ( "2017-05-21 11:33", "e1", 17 ),
//        ( "2017-05-21 11:37", "e2", 18 ),
//        ( "2017-05-21 11:38", "e3", 18 ),
//        ( "2017-05-21 11:39", "e1", 19 ),
//        ( "2017-05-21 11:42", "e2", 19 )
//     ) AS T(Timestamp, Event, Value);


@e1 =
    SELECT ROW_NUMBER() OVER(ORDER BY Timestamp) AS rn,
           *
    FROM @data
    WHERE Event == "e1";

@e2 =
    SELECT ROW_NUMBER() OVER(ORDER BY Timestamp) AS rn,
           *
    FROM @data
    WHERE Event == "e2";

@working =
    SELECT
        (e2.Timestamp - e1.Timestamp).TotalSeconds AS diff_sec,
        (e2.Timestamp - e1.Timestamp).ToString() AS diff_hhmmss,
        e1.Timestamp AS ts1,
        e2.Timestamp AS ts2
    FROM @e1 AS e1
            INNER JOIN @e2 AS e2 ON e1.rn == e2.rn;


OUTPUT @working TO "/output/output.csv"
USING Outputters.Csv(quoting:false);

我的结果,显示样本数据的4分钟和3分钟:

Results

这对你有用吗?如果没有,请提供更实际的数据样本。

答案 1 :(得分:1)

@data =
    SELECT
        LAST_VALUE(Event == "e1" ? Timestamp : (DateTime?)null) OVER (ORDER BY Timestamp) AS E1Time
        // MAX(Event == "e1" ? Timestamp : DateTime.MinValue) OVER (ORDER BY Timestamp) AS E1Time
        , Timestamp AS E2Time
    FROM @events
    HAVING Event == "e2"
    ;

因为聚合/ WF 忽略 null(至少他们应该,LAST_VALUE的U-SQL文档没有说明,所以需要验证)。这允许模拟条件行为,例如WHEN。使用MAX / MIN和适当的默认值可以获得类似的行为。

也就是说,您应该详细说明输入数据和预期结果,这可能会改变解决方案。也就是说,如果出现异常数据序列并且预期会出现什么行为(或者为了简单起见至少可以容忍):

  1. e1,e1,e2 - 上面的代码忽略了之前的e1
  2. e1,e2,e2 - 上面的代码计算了相同e1的2个值
  3. e1,e1,e2,e2 - 上述代码无法识别嵌套,与案例2相同。
  4. e2 - 上面的代码可能会崩溃(null)或使用DateTime.MinValue抛出结果。
  5. 等。在某些复杂的情况下,你可能不得不通过REDUCE ALL推迟自定义减速器(这是最后的手段!),但这会限制可以处理的数据的大小。