
# JOIN
#### Equi-join
- **语法格式**
  ```
  FROM tableExpression INNER | LEFT | RIGHT | FULL JOIN tableExpression
    ON value11 = value21 [ AND value12 = value22]
  ```
  
 
- **注意事项**
  - 目前仅支持 equi-join ，即 join 的联合条件至少拥有一个相等谓词。不支持任何 cross join 和 theta join。
  
  - Join 的顺序没有进行优化，join 会按照 FROM 中所定义的顺序依次执行。请确保 join 所指定的表在顺序执行中不会产生不支持的 cross join （笛卡尔积）导致查询失败。
  
  - 流查询中可能会因为不同行的输入数量导致计算结果的状态无限增长。请提供具有有效保留间隔的查询配置，以防止出现过多的状态。
   
- **示例**
  ```
  SELECT *
  FROM Orders INNER JOIN Product ON Orders.productId = Product.id;
  SELECT *
  FROM Orders LEFT JOIN Product ON Orders.productId = Product.id;
  SELECT *
  FROM Orders RIGHT JOIN Product ON Orders.productId = Product.id;
  SELECT *
  FROM Orders FULL OUTER JOIN Product ON Orders.productId = Product.id;
  ```
  
#### Time-windowed Join
- **功能描述**
  每条流的每一条数据会与另一条流上的不同时间区域的数据进行JOIN。
  
- **语法格式**
  ```
  from t1 JOIN t2 ON t1.key = t2.key AND TIMEBOUND_EXPRESSION
  ```
  
- **语法描述**
  TIMEBOUND_EXPRESSION 有两种写法，如下：
  - L.time between LowerBound(R.time) and UpperBound(R.time)
  
  - R.time between LowerBound(L.time) and UpperBound(L.time)
   
  带有时间属性(L.time/R.time)的比较表达式。
  
- **注意事项**
  时间窗口join需要至少一个 equi-join 谓词和一个限制了双方时间的 join 条件。
  例如使用两个适当的范围谓词（\<, \<=, \>=, \>），一个 BETWEEN 谓词或一个比较两个输入表中相同类型的时间属性（即处理时间和事件时间）的相等谓词
  比如，以下谓词是合法的窗口 join 条件：
  - ltime = rtime
  
  - ltime \>= rtime AND ltime \< rtime + INTERVAL '10' MINUTE
  
  - ltime BETWEEN rtime - INTERVAL '10' SECOND AND rtime + INTERVAL '5' SECOND
   
 
- **示例**
  所有在收到后四小时内发货的 order 会与它们相关的 shipment 进行 join。
  ```
  SELECT *
  FROM Orders o, Shipments s
  WHERE o.id = s.orderId AND
        o.ordertime BETWEEN s.shiptime - INTERVAL '4' HOUR AND s.shiptime;
  ```
  
#### Expanding arrays into a relation
- **注意事项**
  目前尚未支持非嵌套的 WITH ORDINALITY 。
  
- **示例**
  ```
  SELECT users, tag
  FROM Orders CROSS JOIN UNNEST(tags) AS t (tag);
  ```
  
 
#### Join表函数(UDTF)
- **功能描述**
  将表与表函数的结果进行 join 操作。左表（outer）中的每一行将会与调用表函数所产生的所有结果中相关联行进行 join 。
  
- **注意事项**
  针对横向表的左外部联接当前仅支持文本常量 TRUE 作为谓词。
  
- **示例**
  若表函数返回了空结果，左表（outer）的行将会被删除
  ```
  SELECT users, tag
  FROM Orders, LATERAL TABLE(unnest_udtf(tags)) t AS tag;
  ```
  若表函数返回了空结果，将会保留相对应的外部行并用空值填充
  ```
  SELECT users, tag
  FROM Orders LEFT JOIN LATERAL TABLE(unnest_udtf(tags)) t AS tag ON TRUE;
  ```
  
 
#### Join Temporal Table Function
- **功能描述**
  
  
- **注意事项**
  目前仅支持在 Temporal Tables 上的 inner join。
  
- **示例**
  假如Rates是一个 Temporal Table Function， join 可以使用 SQL 进行如下的表达：
  ```
  SELECT
    o_amount, r_rate
  FROM
    Orders,
    LATERAL TABLE (Rates(o_proctime))
  WHERE
    r_currency = o_currency;
  ```
  
 
#### Join Temporal Tables
- **功能描述**
  与Temporal表进行join操作。
  
- **语法格式**
  ```
  SELECT column-names
  FROM table1  [AS <alias1>]
  [LEFT] JOIN table2 FOR SYSTEM_TIME AS OF table1.proctime [AS <alias2>]
  ON table1.column-name1 = table2.key-name1
  ```
  
- **语法说明**
  - table1.proctime表示table1的proctime处理时间属性(计算列)。
  
  - 使用FOR SYSTEM_TIME AS OF table1.proctime表示当左边表的记录与右边的维表join时，只匹配当前处理时间维表所对应的快照数据。
   
- **注意事项**
  仅支持带有处理时间的 temporal tables 的 inner 和 left join。
  
- **示例**
  假设 LatestRates 是一个根据最新的 rates 物化的Temporal Table。
  ```
  SELECT
    o.amount, o.currency, r.rate, o.amount * r.rate
  FROM
    Orders AS o
    JOIN LatestRates FOR SYSTEM_TIME AS OF o.proctime AS r
    ON r.currency = o.currency;
  ```
  
 
