適用於:
Databricks SQL 勾
Databricks 執行時間 19.0 及以上版本
Important
這項功能位於 測試版 (Beta) 中。 工作區管理員可以從 「預覽 」頁面控制對此功能的存取。 請參閱 管理 Azure Databricks 預覽。
在前一 列的table_reference中尋找並篩選圖案。
MATCH_RECOGNIZE 分割輸入、在每個分割區內排序列、將列模式與該序列匹配,並根據列匹配模式回傳摘要或每列結果。
典型用途包括偵測連續價值的連串、V 形或 W 形價格變動,以及事件串流的時段化。
語法
MATCH_RECOGNIZE (
[ PARTITION BY partition [, ...] ]
[ ORDER BY order_by ]
[ MEASURES measures ]
[ row_pattern_rows_per_match ]
[ AFTER MATCH row_pattern_skip_to ]
PATTERN ( row_pattern )
DEFINE row_pattern_definition_list )
measures
MEASURES { measureExpr AS measureName } [, ...]
row_pattern_rows_per_match
{ ONE ROW PER MATCH
| ALL ROWS PER MATCH [ SHOW EMPTY MATCHES ] }
row_pattern_skip_to
SKIP PAST LAST ROW
Parameters
PARTITION BY分區[, ...]
一個或多個表達式,定義模式匹配所執行的列群。 若省略
PARTITION BY,分割區包含所有列。PARTITION BY僅接受欄位參考。 如果你指定另一個表達式,Azure Databricks會MATCH_RECOGNIZE_PARTITION_BY_MUST_BE_COLUMN。ORDER BY order_by
指定每個分割內列的順序。 模式匹配與導航函數使用此順序。
-
可選擇性地定義每個模式匹配回傳的度量欄位。
row_pattern_rows_per_match
控制每場比賽回傳的排數。 預設值為
ONE ROW PER MATCH。ONE ROW PER MATCH每場比賽回傳一排。 結果僅包含分割欄與測度欄。
ALL ROWS PER MATCH [ SHOW EMPTY MATCHES ]每行參與比賽的行返回一列。 每個輸出列包含該匹配計算出的 、 欄位
PARTITION BY和MEASURES欄位對應的輸入欄位table_reference。SHOW EMPTY MATCHES在 下被接受ALL ROWS PER MATCH,且當你省略空匹配處理子句時,是預設值。 此釋出不會產生空匹配,因此關鍵字對結果沒有可觀察的影響。
賽後row_pattern_skip_to
指定在找到匹配後,從哪一列繼續。 本版本僅支援。
SKIP PAST LAST ROW繼續進行緊接當前比賽最後一排之後的那一列。 這是省略AFTER MATCH該條款時的預設方式。模式 (row_pattern)
指定相符的圖案。
定義 row_pattern_definition_list
定義了
PATTERN和MEASURES子句中所引用的布林變數。
Result
結果取決於每匹配列數模式:
ONE ROW PER MATCH回傳
PARTITION BY欄位,接著MEASURES欄位。ALL ROWS PER MATCH每行參與比賽的行返回一列。 每個輸出列包含該匹配計算出的 、 欄位
PARTITION BY和MEASURES欄位對應的輸入欄位table_reference。
常見錯誤條件
- MATCH_RECOGNIZE_EMPTY_MEASURES
- MATCH_RECOGNIZE_FUNCTION_OUTSIDE_MATCH_RECOGNIZE
- MATCH_RECOGNIZE_MEASURES_MUST_BE_ALIASED
- MATCH_RECOGNIZE_PARTITION_BY_MUST_BE_COLUMN
範例
每個查詢都使用一個 stock_ticker(symbol, tstamp, price) 表格,唯獨最後一個範例使用 page_views(user_id, event_time)。
範例 1:連續上升跑
找出每個符號連續價格上漲的最大連續走勢。 該變數 strt 沒有 DEFINE 項目,因此它會匹配任意一列並錨定執行。
up+ 將配對延伸至一個或多個連續的加分。
PREV(price) 依序讀取緊接前一列 ORDER BY 的價格。
ONE ROW PER MATCH 每次執行會發出一列摘要。
> CREATE OR REPLACE TEMP VIEW stock_ticker AS
SELECT * FROM VALUES
('AAPL', TIMESTAMP '2024-01-01 09:30:00', 100.0),
('AAPL', TIMESTAMP '2024-01-01 09:31:00', 102.0),
('AAPL', TIMESTAMP '2024-01-01 09:32:00', 105.0),
('AAPL', TIMESTAMP '2024-01-01 09:33:00', 104.0),
('AAPL', TIMESTAMP '2024-01-01 09:34:00', 106.0),
('AAPL', TIMESTAMP '2024-01-01 09:35:00', 108.0)
AS t(symbol, tstamp, price);
> SELECT symbol, start_tstamp, end_tstamp, run_length
FROM stock_ticker
MATCH_RECOGNIZE (
PARTITION BY symbol
ORDER BY tstamp
MEASURES FIRST(tstamp) AS start_tstamp,
LAST(tstamp) AS end_tstamp,
COUNT(*) AS run_length
ONE ROW PER MATCH
AFTER MATCH SKIP PAST LAST ROW
PATTERN ( strt up+ )
DEFINE up AS price > PREV(price) ) AS T;
symbol start_tstamp end_tstamp run_length
AAPL 2024-01-01 09:30:00 2024-01-01 09:32:00 3
AAPL 2024-01-01 09:33:00 2024-01-01 09:35:00 3
範例二:V字形(下沉與回退)
偵測一個價格先下跌,然後又上漲。
down+ 與跌倒腿 up+ 及恢復相符。
LAST(down.tstamp) 選擇最後一列分類為 down,即 V 的谷底。變數限定的參考,例如 down.tstamp 允許表達 MEASURES 式讀取與特定模式變數匹配的列。
> SELECT symbol, start_tstamp, bottom_tstamp, end_tstamp
FROM stock_ticker
MATCH_RECOGNIZE (
PARTITION BY symbol
ORDER BY tstamp
MEASURES FIRST(tstamp) AS start_tstamp,
LAST(down.tstamp) AS bottom_tstamp,
LAST(tstamp) AS end_tstamp
ONE ROW PER MATCH
AFTER MATCH SKIP PAST LAST ROW
PATTERN ( strt down+ up+ )
DEFINE down AS price < PREV(price),
up AS price > PREV(price) ) AS T;
symbol start_tstamp bottom_tstamp end_tstamp
AAPL 2024-01-01 09:32:00 2024-01-01 09:33:00 2024-01-01 09:35:00
範例 3:雙底(W 形)
偵測到兩個凹陷,中間有部分回復。 這個模式拼出四條腿(),down1+ up1+ down2+ up2+不同的變數名稱讓你可以獨立測量或過濾每個谷點。
MATCH_NUMBER() 每個 W 在分割區內都被編號。
> CREATE OR REPLACE TEMP VIEW stock_ticker AS
SELECT * FROM VALUES
('AAPL', TIMESTAMP '2024-01-01 09:30:00', 100.0),
('AAPL', TIMESTAMP '2024-01-01 09:31:00', 96.0),
('AAPL', TIMESTAMP '2024-01-01 09:32:00', 92.0),
('AAPL', TIMESTAMP '2024-01-01 09:33:00', 98.0),
('AAPL', TIMESTAMP '2024-01-01 09:34:00', 101.0),
('AAPL', TIMESTAMP '2024-01-01 09:35:00', 95.0),
('AAPL', TIMESTAMP '2024-01-01 09:36:00', 90.0),
('AAPL', TIMESTAMP '2024-01-01 09:37:00', 99.0),
('AAPL', TIMESTAMP '2024-01-01 09:38:00', 104.0)
AS t(symbol, tstamp, price);
> SELECT symbol, start_tstamp, end_tstamp, w_no
FROM stock_ticker
MATCH_RECOGNIZE (
PARTITION BY symbol
ORDER BY tstamp
MEASURES FIRST(tstamp) AS start_tstamp,
LAST(tstamp) AS end_tstamp,
MATCH_NUMBER() AS w_no
ONE ROW PER MATCH
AFTER MATCH SKIP PAST LAST ROW
PATTERN ( strt down1+ up1+ down2+ up2+ )
DEFINE down1 AS price < PREV(price),
up1 AS price > PREV(price),
down2 AS price < PREV(price),
up2 AS price > PREV(price) ) AS T;
symbol start_tstamp end_tstamp w_no
AAPL 2024-01-01 09:30:00 2024-01-01 09:38:00 1
範例四:會話化
將使用者的事件串流合併成多個會話,連續事件之間有超過 30 分鐘的間隔,即可啟動一個新的會話。
strt 在任一排開啟一場遊戲。
same_session* 吸收前一個事件後30分鐘內發生的所有事件。 當差距超過門檻時,比賽結束,下一 AFTER MATCH SKIP PAST LAST ROW 場比賽繼續,並重新開始一場新賽事 MATCH_NUMBER()。
*量詞使單一事件成為有效的一列會話。
> CREATE OR REPLACE TEMP VIEW page_views AS
SELECT * FROM VALUES
(1, TIMESTAMP '2024-01-01 09:00:00'),
(1, TIMESTAMP '2024-01-01 09:15:00'),
(1, TIMESTAMP '2024-01-01 10:00:00'),
(1, TIMESTAMP '2024-01-01 10:10:00')
AS t(user_id, event_time);
> SELECT user_id, session_no, session_start, session_end, event_count
FROM page_views
MATCH_RECOGNIZE (
PARTITION BY user_id
ORDER BY event_time
MEASURES MATCH_NUMBER() AS session_no,
FIRST(event_time) AS session_start,
LAST(event_time) AS session_end,
COUNT(*) AS event_count
ONE ROW PER MATCH
AFTER MATCH SKIP PAST LAST ROW
PATTERN ( strt same_session* )
DEFINE same_session AS event_time <= PREV(event_time) + INTERVAL 30 MINUTE ) AS T;
user_id session_no session_start session_end event_count
1 1 2024-01-01 09:00:00 2024-01-01 09:15:00 2
1 2 2024-01-01 10:00:00 2024-01-01 10:10:00 2