2017-05-21 55 views
1

在我們的項目中,我們必須定期根據收到的輸入數據計算總計和進一步的計算。計算Azure Data Lake Analytics中的時間差異U-SQL作業

一個常見的需求是計算我們輸入數據流中某些行之間的時間差。

例如,這是我的輸入數據流:

時間戳事件價值
2017年5月21日11時33分17 E1
2017年5月21日11點37分18 E2
2017-05- 21 11:38 E3 18
2017年5月21日11:39 E1 19
2017年5月21日11:42 E2 19

我現在要計算所有E2事件和最後接收之間的時間跨度e1事件(按時間戳排序)。

我期望的結果是: 3(分鐘) 4(分鐘)

類似的要求是計算相同類型的事件(即E1的事件之間的所有差異)之間的時間跨度,其中我希望這樣的結果: 6(分鐘)

我嘗試至今:

這類分析中可以很容易地使用LAG函數來實現結合WHEN子句,但不幸的是,WHEN子句是丟失在U - SQL。 如果是T-SQL,也可以在語句的SELECT-Clause中使用Sub-Selects來解決這個問題,但不幸的是這在U-SQL中也是不可能的。

您有任何關於如何解決此問題的建議或示例腳本? 非常感謝您的幫助!

回答

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

這對你有用嗎?如果沒有,請提供更真實的數據樣本。

+0

我覺得它可能更簡單,子查詢可能在U-SQL中。提醒我必須從Itzik Ben-Gan找到我的「差距和島嶼」! – wBob

+0

好東西,鮑勃!這看起來很合理!謝謝! –

+0

在_realistic數據sample_上展開,此解決方案(按設計)需要e1和e2事件之間完美的1:1對應關係。這是一個非常強大的要求 - 只有一個錯誤的時間記錄,錯過的事件,重複的事件等會讓它變得糟糕。在我的經驗中,這種像差往往會出現在現實世界的數據中 - 例如,多機器儀表整理。 – Nabeel

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" 
    ; 

因爲聚集/ WFS 忽略空(至少他們應該爲LAST_VALUE U型SQL文檔不說,所以需要驗證)。這允許仿真諸如WHEN的條件行爲。使用MAX/MIN和適當的默認值可以獲得類似的行爲。

也就是說,您應詳細說明輸入數據和預期結果,這可能會改變解決方案。即,可發生異常的數據序列,並預期什麼樣的行爲(或至少耐受簡單起見),如果他們這樣做:

  1. E1,E1,E2 - 上述代碼忽略較早E1
  2. E1,E2 ,E2 - 上述代碼計算2個值WRT相同E1
  3. E1,E1,E2,E2 - 以上代碼不能識別嵌套,相同情況下2.
  4. E2 - 以上代碼可能會崩潰(空)或拋通過使用DateTime.MinValue結果。

等在複雜的某些時候,你可能得推遲到通過減少所有(這是不得已而爲之!),但會限制可以處理的數據的大小定製的減速。

+0

謝謝你的評論,Nabeel!不過,說實話,我現在完全拋棄了DataLake Analytics,並在SQL Server中使用內存優化表來進行我們所需的分析。我們需要結構化數據的頻繁計算,這就是T-SQL能夠完美地完成的。就我所瞭解的Data Lake Analytics而言,如果我們想要合併非結構化的東西並以較少的頻率進行批處理,那麼它就更好。 –

+0

哈哈我猜你的數據量是非常低的然後。祝你好運! – wBob