Flink系列Table API和SQL之:联结查询-灵析社区

打酱油的后端

一、常规联结查询

  • 常规联结是SQL中原生定义的Join方式,是最通用的一类联结操作。具体语法与标准SQL的联结完全相同,通过关键字JOIN来联结两个表,后面用关键字ON来指明联结条件。
  • 在两个动态表的联结中,任何一侧表的插入(INSERT)或更改(UPDATE)操作都会让联结的结果发生改变。例如,如果左侧有新数据到来,会与右侧表中所有之前的数据进行联结合并,右侧表之后到来的新数据也会与这条数据连接合并。所以,常规联结查询一般是更新Update查询。
  • 与标准SQL一致,Flink SQL的常规联结也可以分为内联结(INNER JOIN)和外联结(OUTER JOIN),区别在于结果中是否包含不符合联结条件的行。目前仅支持"等值条件"作为联结条件,也就是关键字ON后面必须是判断两表中字段相等的逻辑表达式。

1.等值内联结

  • 内联结用INNER JOIN来定义,会返回两表中符合联结条件的所有行的组合,也就是所谓的笛卡尔积。目前仅支持等值联结条件。
  • 例如之前提到的订单表(定义为Order)和商品表(定义为Product)的联结查询,就可以用以下SQL实现:
SELECT * FROM Order
INNER JOIN Product
ON Order.product_id = Product.id
  • 这是一个内联结,联结条件是订单数据的product_id和商品数据的id相等。由于订单表中出现的商品id一定会在商品表中出现,因此这样的到的联结结果表,就包含了订单表Order中所有订单数据对应的详细信息。

2.等值外联结

  • 外联结返回符合联结条件的所有行的笛卡尔积。还可以将某一侧标中找不到任何匹配的行也单独返回。Flink SQL支持左外(LEFT JOIN)、右外(RIGHT JOIN)和全外(FULL OUTER JOIN),分别表示会将左侧表、右侧表以及双侧表中没有任何匹配的行返回。

具体用法如下:

SELECT *
FROM Order 
LEFT JOIN Product
ON Order.product_id = Product.id

二、间隔联结查询

  • DataStream API中的双流Join,包括窗口联结(window join)和间隔联结(interval join)。
  • 两条流的Join就对应着SQL中两个表的Join,这是流处理中特有的联结方式。

间隔联结返回的,同样是符合约束条件的两条数据的笛卡尔积。只不过这里的约束条件除了常规的联结条件外,还多了一个时间间隔的限制。具体语法有以下要点:

  • 两表的联结:间隔联结不需要用JOIN关键字,直接在FROM后将要联结的两表列出来就可以,用逗号分隔。这与标准SQL中的语法一致,表示一个交叉联结,会返回两表中所有行的笛卡尔积。
  • 联结条件:联结条件用WHERE子句来定义,用一个等值表达式描述。交叉联结之后再用WHERE进行条件筛选,效果跟内联结INNER JOIN…ON…非常类似。
  • 时间间隔限制:可以在WHERE子句中,联结条件后用AND追加一个时间间隔的限制条件:做法是提取左右两侧表中的时间字段,然后用一个表达式来指明两者需要满足的间隔限制。具体定义方式有下面三种,这里分别用ltime和rtime表示左右表中的时间字段:
  1. ltime=rtime
  2. ltime>=rtime AND ltime<rtime+INTERVAL. ‘10’ MINUTE
  3. ltime BETWEEN rtime - INTERVAL ‘10’ SECOND AND rtime + INTERVAL ‘5’ SECOND
  4. 判断两者相等,这是最强的时间约束,要求两表中数据的时间必须完全一致才能匹配。一般情况下,还是会放宽一些,给出一个间隔。间隔的定义可以用<,<=,>=,>这一类的关系不等式,也可以用BETWEEN … AND …这样的表达式。

例如:现在除了订单表Order外,还有一个发货表Shipment,要求在收到订单后四个小时内发货,就可以用一个间隔联结查询,把所以订单与它对应的发货信息连接合并在一起返回:

SELECT *
FROM Order o ,Shipment s
WHERE o.id = s.order_id
AND o.order_time BETWEEN s.ship_time - INTERVAL '4' HOUR AND s.ship_time

在流处理中,间隔联结查询只支持具有时间属性的仅追加表。

  • 除了间隔联结之外,Flink SQL还支持时间联结(Temporal Join),这主意是针对版本表而言的。
  • 所谓版本表,就是记录了数据随着时间推移版本变化的表,可以理解成一个更新日志,就是具有时间属性、还会进行更新操作的表。
  • 当我们联结某个版本表时,并不是把当前的数据连接合并起来就行了,而是希望能够根据数据发生的时间,找到当时的版本。这种根据更新时间提取当时的值进行联结的操作,就叫作"时间联结"。

阅读量:1067

点赞量:0

收藏量:0