共用方式為


Azure Stream Analytics 與 Fabric Eventstream 中的常見查詢模式

備註

Fabric Eventstream 與 Azure Stream Analytics 建置於相同的執行環境。 因此,本文所解釋的概念同時適用於 Azure Stream Analytics 與 Fabric Eventstream。

Azure Stream Analytics 中的查詢以類似 SQL 的查詢語言表達。 這些語言結構已在 Stream Analytics 查詢語言參考 指南中有記錄。

查詢設計可以表達簡單的直通邏輯,將事件資料從一個輸入串流移至輸出資料庫,或可以在不同的時間窗內進行豐富的模式匹配和時間分析來計算聚合,如同在 使用 Stream Analytics 建立 IoT 解決方案 指南中所示。 你可以將多個輸入的資料合併,將串流事件合併,也可以對靜態參考資料做查詢來豐富事件值。 你也可以把資料寫入多個輸出。

本文根據實際情境,概述了幾種常見查詢模式的解決方案。

支援的資料格式

Azure Stream Analytics 支援處理 CSV、JSON 及 Avro 資料格式的事件。 JSON 與 Avro 格式可包含複雜型態,如巢狀物件(記錄)或陣列。 欲了解更多處理這些複雜資料型態的資訊,請參閱 解析 JSON 與 AVRO 資料

將資料傳送到多個輸出

多個 SELECT 語句可用來輸出資料至不同的輸出匯。 例如,一個 SELECT 語句可以輸出基於閾值的警示,而另一個則可以輸出事件到一個 blob 儲存。

請考慮以下 輸入

| Make | Time |
| --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |
| Make1 |2023-01-01T00:00:02.0000000Z |
| Make2 |2023-01-01T00:00:01.0000000Z |
| Make2 |2023-01-01T00:00:02.0000000Z |
| Make2 |2023-01-01T00:00:03.0000000Z |

此外,你希望查詢能產生以下兩個結果:

檔案輸出

| Make | Time |
| --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |
| Make1 |2023-01-01T00:00:02.0000000Z |
| Make2 |2023-01-01T00:00:01.0000000Z |
| Make2 |2023-01-01T00:00:02.0000000Z |
| Make2 |2023-01-01T00:00:03.0000000Z |

警示輸出

| Make | Time | Count |
| --- | --- | --- |
| Make2 |2023-01-01T00:00:10.0000000Z |3 |

以兩個 SELECT 語句查詢,輸出為 Archive 與 Alert

SELECT
	*
INTO
	ArchiveOutput
FROM
	Input TIMESTAMP BY Time

SELECT
	Make,
	System.TimeStamp() AS Time,
	COUNT(*) AS [Count]
INTO
	AlertOutput
FROM
	Input TIMESTAMP BY Time
GROUP BY
	Make,
	TumblingWindow(second, 10)
HAVING
	[Count] >= 3

INTO 子句告訴串流分析服務,將資料寫入哪個輸出。 第一個 SELECT 定義了一個直通查詢,從輸入接收資料並傳送到名為 ArchiveOutput 的輸出。 第二個查詢會彙整並過濾資料,然後將結果傳送到名為 AlertOutput 的下游警示系統輸出。

WITH 子句可用來定義多個子查詢區塊。 此選項的優點是對輸入來源開啟的讀取器較少。

查詢

WITH ReaderQuery AS (
	SELECT
		*
	FROM
		Input TIMESTAMP BY Time
)

SELECT * INTO ArchiveOutput FROM ReaderQuery

SELECT 
	Make,
	System.TimeStamp() AS Time,
	COUNT(*) AS [Count] 
INTO AlertOutput 
FROM ReaderQuery
GROUP BY
	Make,
	TumblingWindow(second, 10)
HAVING [Count] >= 3

欲了解更多資訊,請參閱 WITH 條款

簡單直通查詢

可使用簡單的直通查詢將輸入串流資料複製到輸出。 例如,若一串包含即時車輛資訊的資料需要儲存在 SQL 資料庫以供後續分析,簡單的直通查詢即可完成。

請考慮以下 輸入

| Make | Time | Weight |
| --- | --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |"1000" |
| Make1 |2023-01-01T00:00:02.0000000Z |"2000" |

你希望 輸出 和輸入相同:

| Make | Time | Weight |
| --- | --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |"1000" |
| Make1 |2023-01-01T00:00:02.0000000Z |"2000" |

問題是這樣的:

SELECT
	*
INTO Output
FROM Input

SELECT * 查詢會投影傳入事件的所有欄位,並將它們傳送到輸出。 相反地,你可以只投影 SELECT 語句中的必填欄位。 以下範例中, SELECT 陳述式僅從輸入資料中投影 MakeTime 欄位。

請考慮以下 輸入

| Make | Time | Weight |
| --- | --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |1000 |
| Make1 |2023-01-01T00:00:02.0000000Z |2000 |
| Make2 |2023-01-01T00:00:04.0000000Z |1500 |

你希望 輸出 只包含 Make 和 Time 欄位:

| Make | Time |
| --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |
| Make1 |2023-01-01T00:00:02.0000000Z |
| Make2 |2023-01-01T00:00:04.0000000Z |

以下是只顯示必要欄位的 查詢

SELECT
	Make, Time
INTO Output
FROM Input

使用 LIKE 和 NOT LIKE 進行字串比對

LIKENOT LIKE 可用來驗證欄位是否符合某種模式。 例如,你可以用過濾器只回傳以字母 A 開頭、以數字 9結尾的車牌。

請考慮以下 輸入

| Make | License_plate | Time |
| --- | --- | --- |
| Make1 |ABC-123 |2023-01-01T00:00:01.0000000Z |
| Make2 |AAA-999 |2023-01-01T00:00:02.0000000Z |
| Make3 |ABC-369 |2023-01-01T00:00:03.0000000Z |

你希望 輸出 的車牌是以字母 A 開頭,以數字 9結尾:

| Make | License_plate | Time |
| --- | --- | --- |
| Make2 |AAA-999 |2023-01-01T00:00:02.0000000Z |
| Make3 |ABC-369 |2023-01-01T00:00:03.0000000Z |

這裡有一個使用 LIKE 運算子的 查詢

SELECT
	*
FROM
	Input TIMESTAMP BY Time
WHERE
	License_plate LIKE 'A%9'

使用 LIKE 陳述來檢查 License_plate 欄位的值。 它應該以字母 A開頭,接著是任意一串零字元或更多字元,最後以數字 9 結尾。

過去事件的計算

LAG 函數可用於檢視某一時間窗內的過去事件,並與當前事件做比較。 例如,如果當前車輛的品牌與上一次通過收費站的車輛不同,則可以輸出出該車的品牌。

範例 輸入

| Make | Time |
| --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |
| Make2 |2023-01-01T00:00:02.0000000Z |

範例 輸出

| Make | Time |
| --- | --- |
| Make2 |2023-01-01T00:00:02.0000000Z |

範例 查詢

SELECT
	Make,
	Time
FROM
	Input TIMESTAMP BY Time
WHERE
	LAG(Make, 1) OVER (LIMIT DURATION(minute, 1)) <> Make

使用 LAG 查看前一個事件的輸入串流,取得 Make 值並與當前事件的 Make 值比較,輸出事件。

欲了解更多資訊,請參閱 LAG。

傳回視窗中的最後一個事件

由於系統會即時處理事件,沒有函式能判斷事件是否是該時間窗口內最後抵達的事件。 為了達成此目的,輸入串流需要與另一個串流進行連接,在該串流中某事件的時間為該視窗中所有事件的最大時間。

範例 輸入

| License_plate | Make | Time |
| --- | --- | --- |
| DXE 5291 |Make1 |2023-07-27T00:00:05.0000000Z |
| YZK 5704 |Make3 |2023-07-27T00:02:17.0000000Z |
| RMV 8282 |Make1 |2023-07-27T00:05:01.0000000Z |
| YHN 6970 |Make2 |2023-07-27T00:06:00.0000000Z |
| VFE 1616 |Make2 |2023-07-27T00:09:31.0000000Z |
| QYF 9358 |Make1 |2023-07-27T00:12:02.0000000Z |
| MDR 6128 |Make4 |2023-07-27T00:13:45.0000000Z |

範例輸出,其中包含兩個 10 分鐘時間視窗內最後幾輛車的資訊:

| License_plate | Make | Time |
| --- | --- | --- |
| VFE 1616 |Make2 |2023-07-27T00:09:31.0000000Z |
| MDR 6128 |Make4 |2023-07-27T00:13:45.0000000Z |

範例 查詢

WITH LastInWindow AS
(
	SELECT 
		MAX(Time) AS LastEventTime
	FROM 
		Input TIMESTAMP BY Time
	GROUP BY 
		TumblingWindow(minute, 10)
)

SELECT 
	Input.License_plate,
	Input.Make,
	Input.Time
FROM
	Input TIMESTAMP BY Time 
	INNER JOIN LastInWindow
	ON DATEDIFF(minute, Input, LastInWindow) BETWEEN 0 AND 10
	AND Input.Time = LastInWindow.LastEventTime

查詢的第一步是找出 10 分鐘視窗中最大時間戳,也就是該視窗上一次事件的時間戳。 第二步將第一個查詢的結果與原始串流結合,以找出每個視窗中與最後時間戳記相符的事件。

DATEDIFF 是一個特定日期的函式,用來比較並回傳兩個 DateTime 欄位間的時間差,更多資訊請參見 日期函數

欲了解更多關於加入串流的資訊,請參閱 JOIN。

隨時間進行的資料彙整

要計算一個時間窗內的資訊,你可以將資料彙整。 在這個例子中,語句計算每個特定車款在過去10秒時間內的計數。

範例 輸入

| Make | Time | Weight |
| --- | --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |1000 |
| Make1 |2023-01-01T00:00:02.0000000Z |2000 |
| Make2 |2023-01-01T00:00:04.0000000Z |1500 |

範例 輸出

| Make | Count |
| --- | --- |
| Make1 | 2 |
| Make2 | 1 |

查詢

SELECT
	Make,
	COUNT(*) AS Count
FROM
	Input TIMESTAMP BY Time
GROUP BY
	Make,
	TumblingWindow(second, 10)

這個彙整會依 品牌 分組車輛,並每10秒統計一次。 輸出結果顯示通過收費站的車輛品牌與數量

TumblingWindow 是一個用於將事件分組的視窗函式。 聚合可以套用於所有分組事件上。 欲了解更多資訊,請參閱 視窗功能

欲了解更多聚合資訊,請參閱 聚合函數

定期輸出數值

當事件缺失或不規則時,可以從較稀疏的資料輸入產生規律區間輸出。 例如,每 5 秒產生一個事件,報告最近一次看到的資料點。

範例 輸入

| Time | Value |
| --- | --- |
| "2014-01-01T06:01:00" |1 |
| "2014-01-01T06:01:05" |2 |
| "2014-01-01T06:01:10" |3 |
| "2014-01-01T06:01:15" |4 |
| "2014-01-01T06:01:30" |5 |
| "2014-01-01T06:01:35" |6 |

範例輸出(前10行):

| Window_end | Last_event.Time | Last_event.Value |
| --- | --- | --- |
| 2014-01-01T14:01:00.000Z |2014-01-01T14:01:00.000Z |1 |
| 2014-01-01T14:01:05.000Z |2014-01-01T14:01:05.000Z |2 |
| 2014-01-01T14:01:10.000Z |2014-01-01T14:01:10.000Z |3 |
| 2014-01-01T14:01:15.000Z |2014-01-01T14:01:15.000Z |4 |
| 2014-01-01T14:01:20.000Z |2014-01-01T14:01:15.000Z |4 |
| 2014-01-01T14:01:25.000Z |2014-01-01T14:01:15.000Z |4 |
| 2014-01-01T14:01:30.000Z |2014-01-01T14:01:30.000Z |5 |
| 2014-01-01T14:01:35.000Z |2014-01-01T14:01:35.000Z |6 |
| 2014-01-01T14:01:40.000Z |2014-01-01T14:01:35.000Z |6 |
| 2014-01-01T14:01:45.000Z |2014-01-01T14:01:35.000Z |6 |

範例 查詢

SELECT
	System.Timestamp() AS Window_end,
	TopOne() OVER (ORDER BY Time DESC) AS Last_event
FROM
	Input TIMESTAMP BY Time
GROUP BY
	HOPPINGWINDOW(second, 300, 5)

此查詢每 5 秒產生一次事件,並輸出先前收到的最後一次事件。 HOPPINGWINDOW 的持續時間決定查詢回溯到多久以尋找最新事件。

更多資訊請參閱 跳躍視窗

將溪流中的事件相關起來

同一串流中的相關事件可以透過使用 LAG 函數查看過去事件來完成。 例如,在過去 90 秒內,如果來自相同廠牌的兩輛連續車輛通過收費站,就可以產生輸出。

範例 輸入

| Make | License_plate | Time |
| --- | --- | --- |
| Make1 |ABC-123 |2023-01-01T00:00:01.0000000Z |
| Make1 |AAA-999 |2023-01-01T00:00:02.0000000Z |
| Make2 |DEF-987 |2023-01-01T00:00:03.0000000Z |
| Make1 |GHI-345 |2023-01-01T00:00:04.0000000Z |

範例 輸出

| Make | Time | Current_car_license_plate | First_car_license_plate | First_car_time |
| --- | --- | --- | --- | --- |
| Make1 |2023-01-01T00:00:02.0000000Z |AAA-999 |ABC-123 |2023-01-01T00:00:01.0000000Z |

範例 查詢

SELECT
	Make,
	Time,
	License_plate AS Current_car_license_plate,
	LAG(License_plate, 1) OVER (LIMIT DURATION(second, 90)) AS First_car_license_plate,
	LAG(Time, 1) OVER (LIMIT DURATION(second, 90)) AS First_car_time
FROM
	Input TIMESTAMP BY Time
WHERE
	LAG(Make, 1) OVER (LIMIT DURATION(second, 90)) = Make

LAG 函式可以查看前一次事件的輸入串流,取得 Make 值,並將其與當前事件的 Make 值做比較。 一旦條件達成,就可以在 SELECT 語句中使用 LAG 投影前一次事件的資料。

欲了解更多資訊,請參閱 LAG。

偵測事件之間的時間長度

事件的持續時間可以透過在收到 End 事件後查看最後一次 Start 事件來計算。 此查詢有助於判斷使用者在某頁面或功能上花費的時間。

範例 輸入

| User | Feature | Event | Time |
| --- | --- | --- | --- |
| user@location.com |RightMenu |Start |2023-01-01T00:00:01.0000000Z |
| user@location.com |RightMenu |End |2023-01-01T00:00:08.0000000Z |

範例 輸出

| User | Feature | Duration |
| --- | --- | --- |
| user@location.com |RightMenu |7 |

範例 查詢

SELECT
	[user],
	feature,
	DATEDIFF(
		second,
		LAST(Time) OVER (PARTITION BY [user], feature LIMIT DURATION(hour, 1) WHEN Event = 'start'),
		Time) as duration
FROM input TIMESTAMP BY Time
WHERE
	Event = 'end'

LAST 函式可用於在特定條件下擷取最後事件。 在此範例中,條件為 Start,將搜尋依 PARTITION BY 使用者與功能劃分。 如此一來,當搜尋 Start 事件時,每位使用者及每項功能都能被獨立地處理。 限制持續時間 限制搜尋時間回溯至結束與開始事件之間的1小時內。

計算不重複的值

COUNTDISTINCT 可用來計算在某個時間窗內串流中出現的獨特欄位值數量。 您可以建立查詢,以計算在 2 秒視窗內,通過收費站之車輛的唯一廠牌數量。

範例 輸入

| Make | Time |
| --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |
| Make1 |2023-01-01T00:00:02.0000000Z |
| Make2 |2023-01-01T00:00:01.0000000Z |
| Make2 |2023-01-01T00:00:02.0000000Z |
| Make2 |2023-01-01T00:00:03.0000000Z |

範例 輸出:

| Count_make | Time |
| --- | --- |
| 2 |2023-01-01T00:00:02.000Z |
| 1 |2023-01-01T00:00:04.000Z |

範例 查詢:

SELECT
     COUNT(DISTINCT Make) AS Count_make,
     System.TIMESTAMP() AS Time
FROM Input TIMESTAMP BY TIME
GROUP BY 
     TumblingWindow(second, 2)

COUNT(DISTINCT Make) 會在時間區間內回傳 Make 欄中不同值的計數。 更多資訊請參閱 COUNT 聚合函數

在視窗中取得第一個事件

你可以用 IsFirst 在時間窗內取得第一個事件。 例如,每隔10分鐘輸出第一輛車的資訊。

範例 輸入

| License_plate | Make | Time |
| --- | --- | --- |
| DXE 5291 |Make1 |2023-07-27T00:00:05.0000000Z |
| YZK 5704 |Make3 |2023-07-27T00:02:17.0000000Z |
| RMV 8282 |Make1 |2023-07-27T00:05:01.0000000Z |
| YHN 6970 |Make2 |2023-07-27T00:06:00.0000000Z |
| VFE 1616 |Make2 |2023-07-27T00:09:31.0000000Z |
| QYF 9358 |Make1 |2023-07-27T00:12:02.0000000Z |
| MDR 6128 |Make4 |2023-07-27T00:13:45.0000000Z |

範例 輸出

| License_plate | Make | Time |
| --- | --- | --- |
| DXE 5291 |Make1 |2023-07-27T00:00:05.0000000Z |
| QYF 9358 |Make1 |2023-07-27T00:12:02.0000000Z |

範例 查詢

SELECT 
	License_plate,
	Make,
	Time
FROM 
	Input TIMESTAMP BY Time
WHERE 
	IsFirst(minute, 10) = 1

IsFirst 也可以對資料進行分割,並在每個 10 分鐘區間中,針對找到的每個特定車輛廠牌計算第一個事件。

範例 輸出

| License_plate | Make | Time |
| --- | --- | --- |
| DXE 5291 |Make1 |2023-07-27T00:00:05.0000000Z |
| YZK 5704 |Make3 |2023-07-27T00:02:17.0000000Z |
| YHN 6970 |Make2 |2023-07-27T00:06:00.0000000Z |
| QYF 9358 |Make1 |2023-07-27T00:12:02.0000000Z |
| MDR 6128 |Make4 |2023-07-27T00:13:45.0000000Z |

範例 查詢

SELECT 
	License_plate,
	Make,
	Time
FROM 
	Input TIMESTAMP BY Time
WHERE 
	IsFirst(minute, 10) OVER (PARTITION BY Make) = 1

欲了解更多資訊,請參閱 IsFirst

移除視窗中的重複事件

當你執行像計算特定時間窗口內事件平均值等操作時,重複事件應該被過濾。 以下例子中,第二個事件是第一個事件的重複。

範例 輸入

| DeviceId | Time | Attribute | Value |
| --- | --- | --- | --- |
| 1 |2018-07-27T00:00:01.0000000Z |Temperature |50 |
| 1 |2018-07-27T00:00:01.0000000Z |Temperature |50 |
| 2 |2018-07-27T00:00:01.0000000Z |Temperature |40 |
| 1 |2018-07-27T00:00:05.0000000Z |Temperature |60 |
| 2 |2018-07-27T00:00:05.0000000Z |Temperature |50 |
| 1 |2018-07-27T00:00:10.0000000Z |Temperature |100 |

範例 輸出

| AverageValue | DeviceId |
| --- | --- |
| 70 | 1 |
|45 | 2 |

範例 查詢

WITH Temp AS (
	SELECT Value, DeviceId
	FROM Input TIMESTAMP BY Time
	GROUP BY Value, DeviceId, System.Timestamp()
)
 

SELECT
	AVG(Value) AS AverageValue, DeviceId
INTO Output
FROM Temp
GROUP BY DeviceId,TumblingWindow(minute, 5)

當第一個語句執行時,重複記錄會合併成一個,因為 group by 子句中的欄位都是相同的。 因此,它會移除重複的部分。

為不同案例/值(CASE 陳述式)指定邏輯

CASE 陳述可以根據特定準則,針對不同欄位提供不同的計算。 例如,將車道 A 指派給 Make1 的車輛,而將車道 B 指派給任何其他廠牌。

範例 輸入

| Make | Time |
| --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |
| Make2 |2023-01-01T00:00:02.0000000Z |
| Make2 |2023-01-01T00:00:03.0000000Z |

範例 輸出

| Make |Dispatch_to_lane | Time |
| --- | --- | --- |
| Make1 |"A" |2023-01-01T00:00:01.0000000Z |
| Make2 |"B" |2023-01-01T00:00:02.0000000Z |

範例 查詢

SELECT
	Make
	CASE
		WHEN Make = "Make1" THEN "A"
		ELSE "B"
	END AS Dispatch_to_lane,
	System.TimeStamp() AS Time
FROM
	Input TIMESTAMP BY Time

CASE 表達式將表達式與一組簡單表達式進行比較,以決定其結果。 在此範例中,車輛 被 Make1 調往車道 A ,而其他品牌的車輛則被分配到 B車道 。

欲了解更多資訊,請參閱 case 表達式

數據轉換

資料可透過 CAST 方法即時投射。 例如,車輛重量可以從 nvarchar(max) 型轉換為 bigint 型,並用於數值計算。

範例 輸入

| Make | Time | Weight |
| --- | --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |"1000" |
| Make1 |2023-01-01T00:00:02.0000000Z |"2000" |

範例 輸出

| Make | Weight |
| --- | --- |
| Make1 |3000 |

範例 查詢

SELECT
	Make,
	SUM(CAST(Weight AS BIGINT)) AS Weight
FROM
	Input TIMESTAMP BY Time
GROUP BY
	Make,
	TumblingWindow(second, 10)

使用 CAST 語句來指定其資料型態。 請參閱 資料型別(Azure Stream Analytics)上的支援資料類型清單。

有關 資料轉換功能的更多資訊,請參閱。

偵測條件的持續時間

對於跨越多個事件的條件,可用 LAG 函數來識別該條件的持續時間。 例如,假設有錯誤導致所有車輛的重量錯誤(超過20,000磅),必須計算該錯誤的持續時間。

範例 輸入

| Make | Time | Weight |
| --- | --- | --- |
| Make1 |2023-01-01T00:00:01.0000000Z |2000 |
| Make2 |2023-01-01T00:00:02.0000000Z |25000 |
| Make1 |2023-01-01T00:00:03.0000000Z |26000 |
| Make2 |2023-01-01T00:00:04.0000000Z |25000 |
| Make1 |2023-01-01T00:00:05.0000000Z |26000 |
| Make2 |2023-01-01T00:00:06.0000000Z |25000 |
| Make1 |2023-01-01T00:00:07.0000000Z |26000 |
| Make2 |2023-01-01T00:00:08.0000000Z |2000 |

範例 輸出

| Start_fault | End_fault |
| --- | --- |
| 2023-01-01T00:00:02.000Z |2023-01-01T00:00:07.000Z |

範例 查詢

WITH SelectPreviousEvent AS
(
SELECT
	*,
	LAG([time]) OVER (LIMIT DURATION(hour, 24)) as previous_time,
	LAG([weight]) OVER (LIMIT DURATION(hour, 24)) as previous_weight
FROM input TIMESTAMP BY [time]
)

SELECT 
	LAG(time) OVER (LIMIT DURATION(hour, 24) WHEN previous_weight < 20000 ) [Start_fault],
	previous_time [End_fault]
FROM SelectPreviousEvent
WHERE
	[weight] < 20000
	AND previous_weight > 20000

第一個 SELECT 陳述將當前重量測量值與先前測量值相關聯,並將其與當前測量值一起投影。 第二個 SELECT 回溯至上一次 previous_weight 小於20000的事件,其中當前的重量小於20000,並且當前事件的 previous_weight 大於20000。

End_fault是當前的非故障事件,而前一個事件是故障的,Start_fault則是在此之前最後一次非故障事件。

具有獨立時間的過程事件(子串流)

事件可能因事件產生者間的時脈偏移、分割區間的時脈偏斜或網路延遲而延遲或順序錯置。 例如, TollID 2 的裝置時鐘比 TollID 1 慢 5 秒, TollID 3 的裝置時鐘比 TollID 1 慢 10 秒。 可以針對每個收費站獨立進行計算,只考量其自身時鐘資料作為時間戳記。

範例 輸入

| LicensePlate | Make | Time | TollID |
| --- | --- | --- | --- |
| DXE 5291 |Make1 |2023-07-27T00:00:01.0000000Z | 1 |
| YHN 6970 |Make2 |2023-07-27T00:00:05.0000000Z | 1 |
| QYF 9358 |Make1 |2023-07-27T00:00:01.0000000Z | 2 |
| GXF 9462 |Make3 |2023-07-27T00:00:04.0000000Z | 2 |
| VFE 1616 |Make2 |2023-07-27T00:00:10.0000000Z | 1 |
| RMV 8282 |Make1 |2023-07-27T00:00:03.0000000Z | 3 |
| MDR 6128 |Make3 |2023-07-27T00:00:11.0000000Z | 2 |
| YZK 5704 |Make4 |2023-07-27T00:00:07.0000000Z | 3 |

範例 輸出

| TollID | Count |
| --- | --- |
| 1 | 2 |
| 2 | 2 |
| 1 | 1 |
| 3 | 1 |
| 2 | 1 |
| 3 | 1 |

範例 查詢

SELECT
      TollId,
      COUNT(*) AS Count
FROM input
      TIMESTAMP BY Time OVER TollId
GROUP BY TUMBLINGWINDOW(second, 5), TollId

TIMESTAMP OVER BY 條款會獨立使用子串流查看每個裝置的時間軸。 每個 TollID 的輸出事件是在計算過程中產生的,意即事件相對於每個 TollID 是順序的,而不是像所有裝置都在同一個時鐘上一樣重新排序。

欲了解更多資訊,請參閱「TIMESTAM BY OVER」。

會話視窗

會話視窗是指隨著事件發生持續擴大的視窗,若在特定時間內未收到事件或視窗達到最大持續時間,則關閉以進行計算。 此視窗在計算使用者互動資料時特別有用。 當使用者開始與系統互動時,視窗會開始,當沒有其他事件被觀察到時關閉,也就是說使用者已經停止互動。 例如,使用者在瀏覽一個網頁時會記錄點擊次數,可以使用會話視窗來查詢該使用者與網站互動的時間長短。

範例 輸入

| User_id | Time | URL |
| --- | --- | --- |
| 0 | 2017-01-26T00:00:00.0000000Z | "www.example.com/a.html" |
| 0 | 2017-01-26T00:00:20.0000000Z | "www.example.com/b.html" |
| 1 | 2017-01-26T00:00:55.0000000Z | "www.example.com/c.html" |
| 0 | 2017-01-26T00:01:10.0000000Z | "www.example.com/d.html" |
| 1 | 2017-01-26T00:01:15.0000000Z | "www.example.com/e.html" |

範例 輸出

| User_id | StartTime | EndTime | Duration_in_seconds |
| --- | --- | --- | --- |
| 0 | 2017-01-26T00:00:00.0000000Z | 2017-01-26T00:01:10.0000000Z | 70 |
| 1 | 2017-01-26T00:00:55.0000000Z | 2017-01-26T00:01:15.0000000Z | 20 |

範例 查詢

SELECT
	user_id,
	MIN(time) as StartTime,
	MAX(time) as EndTime,
	DATEDIFF(second, MIN(time), MAX(time)) AS duration_in_seconds
FROM input TIMESTAMP BY time
GROUP BY
	user_id,
	SessionWindow(minute, 1, 60) OVER (PARTITION BY user_id)

SELECT 投影與使用者互動相關的資料,以及互動的持續時間。 依使用者和 SessionWindow 將資料分組;如果在 1 分鐘內沒有任何互動,該視窗就會關閉,且最大視窗大小為 60 分鐘。

欲了解更多 SessionWindow 資訊,請參閱 Session 視窗

JavaScript 與 C# 中的使用者自訂函式

備註

本節不適用於 Fabric Eventstream。

Azure Stream Analytics 查詢語言可擴充以 JavaScript 或 C# 語言撰寫的自訂函式。 使用者定義函式(UDF)是自訂且複雜的計算,無法輕易用 SQL 語言表達。 這些 UDF 可以定義一次,並在查詢中多次使用。 例如,UDF 可以用來將十六進位 nvarchar(max) 值轉換成 大整數 值。

範例 輸入

| Device_id | HexValue |
| --- | --- |
| 1 | "B4" |
| 2 | "11B" |
| 3 | "121" |

範例 輸出

| Device_id | Decimal |
| --- | --- |
| 1 | 180 |
| 2 | 283 |
| 3 | 289 |
function hex2Int(hexValue){
	return parseInt(hexValue, 16);
}
public static class MyUdfClass {
	public static long Hex2Int(string hexValue){
		return int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
	}
}
SELECT
	Device_id,
	udf.Hex2Int(HexValue) AS Decimal
From
	Input

用戶定義函數會根據每個消耗事件的 HexValue 計算出 bigint 值。

更多資訊請參閱 JavaScriptC#

進階模式匹配 MATCH_RECOGNIZE

MATCH_RECOGNIZE 是一種先進的模式匹配機制,可用於將事件序列與明確定義的正則表達式模式匹配。 例如,ATM 正在實時監控故障,若在運作期間連續出現兩個警告訊息,管理員需被通知。

輸入

| ATM_id | Operation_id | Return_Code | Time |
| --- | --- | --- | --- |
| 1 | "Entering Pin" | "Success" | 2017-01-26T00:10:00.0000000Z |
| 2 | "Opening Money Slot" | "Success" | 2017-01-26T00:10:07.0000000Z |
| 2 | "Closing Money Slot" | "Success" | 2017-01-26T00:10:11.0000000Z |
| 1 | "Entering Withdraw Quantity" | "Success" | 2017-01-26T00:10:08.0000000Z |
| 1 | "Opening Money Slot" | "Warning" | 2017-01-26T00:10:14.0000000Z |
| 1 | "Printing Bank Balance" | "Warning" | 2017-01-26T00:10:19.0000000Z |

輸出

| ATM_id | First_Warning_Operation_id | Warning_Time |
| --- | --- | --- |
| 1 | "Opening Money Slot" | 2017-01-26T00:10:14.0000000Z |
SELECT *
FROM input TIMESTAMP BY time OVER ATM_id
MATCH_RECOGNIZE (
	LIMIT DURATION(minute, 1)
	PARTITION BY ATM_id
	MEASURES
		First(Warning.ATM_id) AS ATM_id,
		First(Warning.Operation_Id) AS First_Warning_Operation_id,
		First(Warning.Time) AS Warning_Time
	AFTER MATCH SKIP TO NEXT ROW
	PATTERN (Success+ Warning{2,})
	DEFINE
		Success AS Success.Return_Code = 'Success',
		Warning AS Warning.Return_Code <> 'Success'
) AS patternMatch

此查詢會匹配至少兩次連續的故障事件,當條件達成時會產生警報。 PATTERN 定義了用於匹配的正則表達式,在此例中,至少在一次成功操作後連續兩次警告。 成功與警告是透過Return_Code值定義的,一旦條件達成,就會執行。 MEASURES** 會連同 ATM_id、第一個警告作業,以及第一個警告時間一起投影。

更多資訊請參見 MATCH_RECOGNIZE

地理圍欄與地理空間查詢

Azure Stream Analytics 內建地理空間功能,可用於實作車隊管理、共乘、連網汽車及資產追蹤等場景。 地理空間資料可以以 GeoJSON 或 WKT 格式作為事件串流或參考資料的一部分被導入。 例如,一家專門製造護照印刷機的公司,會將機器租給政府和領事館。 這些機器的位置受到嚴格管控,以避免護照遺失及偽造用途。 每台機器都裝有 GPS 追蹤器,這些資訊會回傳到 Azure Stream Analytics 的作業。 製造商希望能追蹤這些機器的位置,並在其中一台離開授權區域時獲得警示,這樣他們就能遠端停用、通知主管機關並取回設備。

輸入

| Equipment_id | Equipment_current_location | Time |
| --- | --- | --- |
| 1 | "POINT(-122.13288797982818 47.64082002051315)" | 2017-01-26T00:10:00.0000000Z |
| 1 | "POINT(-122.13307252987875 47.64081350934929)" | 2017-01-26T00:11:00.0000000Z |
| 1 | "POINT(-122.13308862313283 47.6406508603241)" | 2017-01-26T00:12:00.0000000Z |
| 1 | "POINT(-122.13341048821462 47.64043760861279)" | 2017-01-26T00:13:00.0000000Z |

參考資料輸入

| Equipment_id | Equipment_lease_location |
| --- | --- |
| 1 | "POLYGON((-122.13326028450979 47.6409833866794,-122.13261655434621 47.6409833866794,-122.13261655434621 47.64061471602751,-122.13326028450979 47.64061471602751,-122.13326028450979 47.6409833866794))" |

輸出

| Equipment_id | Equipment_alert_location | Time |
| --- | --- | --- |
| 1 | "POINT(-122.13341048821462 47.64043760861279)" | 2017-01-26T00:13:00.0000000Z |
SELECT
	input.Equipment_id AS Equipment_id,
	input.Equipment_current_location AS Equipment_current_location,
	input.Time AS Time
FROM input TIMESTAMP BY time
JOIN
	referenceInput 
	ON input.Equipment_id = referenceInput.Equipment_id
	WHERE 
		ST_WITHIN(input.Equipment_current_location, referenceInput.Equipment_lease_location) = 1

此查詢讓製造商能自動監控機器位置,當機器離開允許的地理圍欄時,立即收到警示。 內建的地理空間功能讓使用者能在查詢中使用 GPS 資料,無需第三方函式庫。

欲了解更多資訊,請參閱 Azure Stream Analytics 的地理圍欄和地理空間聚合應用情境 之文章。

尋求幫助

如需進一步的協助,請嘗試 Azure 串流分析的 Microsoft 問與答頁面

下一步