天天看點

維表JOIN語句

本頁目錄

維表是一張不斷變化的表(不更新的表是變化表的一種特例)。

如何查詢或JOIN一張不斷變化的表? 如果用傳統的JOIN文法來表達

JOIN dim_table ON xxx

,會導緻多次運作得到的結果不一緻。是以在查詢或JOIN維表的時候,需要明确指名要檢視的是維表的哪個時刻的快照。是以,需要引入 SQL:2011 的Temporal Table語義。

維表DDL

Flink SQL中沒有專門為維表設計的DDL文法,使用标準的 

CREATE TABLE

 文法即可,同時需額外增加一行

PERIOD FOR SYSTEM_TIME

的聲明。這行聲明定義了維表的變化周期,即表明該表是一張會變化的表。

維表DDL示例

  1. CREATE TABLE white_list (

  2. id varchar,

  3. name varchar,

  4. age int,

  5. PRIMARY KEY (id), -- 用作維表的話,必須有聲明的主鍵

  6. PERIOD FOR SYSTEM_TIME

  7. ) with (

  8. type = 'xxx',

  9. ...

  10. )

維表具體聲明方式和參數請參見

維表建立

注意:聲明一個維表時,必須指明主鍵。維表JOIN時,ON的條件必須包含所有主鍵的等值條件。

維表JOIN

維表是一張不斷變化的表,是以在JOIN維表的時候,需指明這條記錄關聯維表哪個時刻的快照。目前僅支援關聯目前時刻的維表(未來會支援關聯左表rowtime所對應的維表快照)。

維表JOIN文法

  1. SELECT column-names

  2. FROM table1 [AS <alias1>]

  3. [LEFT] JOIN table2 FOR SYSTEM_TIME AS OF PROCTIME() [AS <alias2>]

  4. ON table1.column-name1 = table2.key-name1

  • 維表支援

    INNER JOIN

    LEFT JOIN

    ,不支援

    RIGHT JOIN

    FULL JOIN

  • JOIN維表時,在維表後必須加上

    FOR SYSTEM_TIME AS OF PROCTIME()

    說明:

    FOR SYSTEM_TIME AS OF PROCTIME()

    含義是:JOIN維表目前時刻所看到的每條資料。
  • 維表JOIN工作模式是左表的一條記錄到達時,在維表中查詢并關聯上比對的資料。如果維表插入了一條資料能比對上之前左表的資料時,JOIN的結果流不會發出更新的資料以彌補之前的未比對。
  • JOIN行為隻發生在處理時間(processing time),即使維表中的資料都被删了,之前JOIN流已經發出的關聯上的資料也不會被撤回或改變。

例如,事件流JOIN白名單維表的SQL如下。

  1. SELECT e.*, w.*

  2. FROM event AS e

  3. JOIN white_list FOR SYSTEM_TIME AS OF PROCTIME() AS w

  4. ON e.id = w.id

注意:
  1. 維表JOIN的ON條件中一定要有包括維表primary key的等值條件,因為需要根據key來查維表。ON條件中可以有其他條件,例如 

    ON event.id = white_list.id AND event.name = white_list.name

    ,其他條件需要包含所有維表主鍵的等值條件。
  2. 維表和維表不能做JOIN。DDL聲明的字段、主鍵等需要和真實表裡面定義的一緻。

維表示例

測試資料

nameinfo:

id(bigint) name(VARCHAR) age(bigint)
1 lilei 22
2 hanmeimei 20
3 libai 28

phoneNumber:

phoneNumber(bigint)
dufu 18867889855
baijuyi 18867889856
18867889857
18867889858

測試語句

  1. CREATE TABLE datahub_input1 (

  2. id BIGINT,

  3. name VARCHAR,

  4. age BIGINT

  5. ) WITH (

  6. type='datahub'

  7. );

  8. create table phoneNumber(

  9. name VARCHAR,

  10. phoneNumber bigint,

  11. primary key(name),

  12. PERIOD FOR SYSTEM_TIME

  13. )with(

  14. type='rds'

  15. );

  16. CREATE table result_infor(

  17. id bigint,

  18. phoneNumber bigint,

  19. name VARCHAR

  20. )with(

  21. type='rds'

  22. );

  23. INSERT INTO result_infor

  24. SELECT

  25. t.id

  26. ,w.phoneNumber

  27. ,t.name

  28. FROM datahub_input1 as t

  29. JOIN phoneNumber FOR SYSTEM_TIME AS OF PROCTIME() as w

  30. ON t.name = w.name;

測試結果

name(varchar)

本文轉自實時計算——

維表JOIN語句