JOIN(Azure 流分析)

与标准的 T-SQL 一样,Azure 流分析查询语言中的 JOIN 用于组合两个或更多个输入源中的记录。 Azure 流分析中的 JOIN 在性质上是短暂的,也就是说,每个 JOIN 必须对匹配行的分离时限施加某种限制。 例如,如果"将 TollBoothEntry 事件与 TollBoothExit 事件联接在同一个 LicensePlate 和 TollId 上且彼此在 5 分钟内发生"是合法的;但"在 LicensePlate 和 TollId 上出现 TollBoothEntry 事件时,将 TollBoothEntry 事件与 TollBoothExit 事件联接"不是 - 它将每个 TollBoothEntry 与所有 TollBoothExit 的无限集合与相同的 LicensePlate 和 TollId 匹配。

使用 DATEDIFF 函数在 JOIN 的 ON 子句内指定关系的时限。 DATEDIFF 的最大大小为 7 天。 有关其常规用途详细信息,请参阅 DATEDIFF (Azure 流分析) 。 在 JOIN 条件中使用 DATEDIFF 时,第二和第三个参数将得到特殊处理。

此外,SELECT * 不能用于 JOIN 语句。

语法

[ FROM { <input_source> } [ ,...n ] ]  
<input_source> ::=   
{  
    input_name [ [ AS ] input_alias ]   
    | <joined_table>   
}  
  
<joined_table> ::=   
{  
    <input_source> <join_type> <input_source> ON <join_condition>   
    | [ <input_source> <join_type> <reference_data> ON <join_condition> ]  
    | [ ( ] <joined_table> [ ) ]   
}  
<join_type> ::=   
    [ { INNER | LEFT [ OUTER ] } ] JOIN  
  

参数

<input_source>

指定输入数据源。

<reference_data>

要 input_source 联接到的引用数据。 有关详细信息,请参阅“引用数据联接”部分。

<join_type>

指定联接操作的类型。

JOIN

指示应在指定的输入源和/或引用数据之间发生指定的联接操作。 左侧和右侧符合联接条件的所有行将包含在结果集中。

警告

如果 JOIN 源已分区,则 JOIN 谓词必须包含与两个源的分区键匹配的条件。

[ LEFT OUTER JOIN ]

指定在结果集中包括左表中所有不满足联接条件的行,除了由内部联接返回所有的行之外,还将另外一个表的输出列设置为 NULL。

ON <join_condition>

指定联接所基于的条件。 联接条件必须具有为关系定义的时间限制或临时结构空间,并且使用 JOIN 函数的特殊 DATEDIFF 函数的特殊语法在 JOIN 的 ON 子句中指定。

示例

在 Azure 流分析中,所有事件都具有定义明确的时间戳。 因此,用户必须在 DATEDIFF 函数中直接使用行别名,如下所示:

SELECT I1.TollId, I1.EntryTime,I2.ExitTime, I1.LicensePlate, DATEDIFF(minute,I1.EntryTime,I2.ExitTime) AS DurationInMinutes   
FROM Input1 I1 TIMESTAMP BY EntryTime   
JOIN Input2 I2 TIMESTAMP BY ExitTime  
ON DATEDIFF(minute,I1,I2) BETWEEN 0 AND 15  
  

当且仅当 ExitTime 发生 EntryTime 之后但落后时间不超过 15 分钟时,上面的联接条件才会生成匹配项。

注意

SELECT 语句中使用的 DATEDIFF 使用常规语法,其中 datetime 列或表达式作为第二个参数和第三个参数传入。 但是,在 JOIN 条件内使用 DATEDIFF 函数时,input_source名称或别名。 在内部,将选择该源中每个事件关联的时间戳。

时限条件可以相互组合,并可与 ON 子句中的其他条件相组合,例如:

SELECT I1.TollId, I1.EntryTime, I2.ExitTime, I1.LicensePlate, DATEDIFF(minute,I1.EntryTime,I2.ExitTime) AS DurationinMinutes   
FROM Input1 I1 TIMESTAMP BY EntryTime   
JOIN Input2 I2 TIMESTAMP BY ExitTime  
ON I1.TollId=I2.TollId  
AND I1.LicensePlate=I2.LicensePlate  
AND DATEDIFF(minute,I1,I2) BETWEEN 0 AND 15  
  

联接三个或多个表时,相同的规则适用于---必须确保所有匹配的事件在有限的时间内相互发生。 例如,若要查找在事务开始和事务结束事件之间发生的所有错误,可以说:

SELECT TS.Id, TS.Name, TS.Amount, E.ErrorCode, E.Description   
FROM TStart TS TIMESTAMP BY TStartTime   
JOIN TEnd TE TIMESTAMP BY TEndTime  
ON DATEDIFF(second, TS, TE) BETWEEEN 0 AND 5  
AND TS.Id = TE.Id  
JOIN Error E TIMESTAMP BY ErrorTime  
ON DATEDIFF(second, TS, E) BETWEEN 0 AND 5
AND DATEDIFF(second, TE, E) < 0
AND E.TId = TS.Id  
  

联接已进行分区的源时,JOIN 谓词必须包括与这两个源的分区键匹配的条件。

SELECT I1.TollId, I1.EntryTime,I2.ExitTime, I1.LicensePlate, DATEDIFF(minute,I1.EntryTime,I2.ExitTime) AS DurationInMinutes   
FROM Input1 I1 TIMESTAMP BY EntryTime PARTITION BY PartitionId  
JOIN Input2 I2 TIMESTAMP BY ExitTime PARTITION BY PartitionId  
ON I1.PartitionId = I2.PartitionId AND DATEDIFF(minute,I1,I2) BETWEEN 0 AND 15  

最后,Azure 流分析默认联接 (左外部联接) 内部联接。 对于内部联接,仅当找到匹配时返回结果。 但是对于 LEFT OUTER 联接,如果联接左侧的事件不匹配,则返回右侧行所有列的带 NULL 的行。 例如,下面是一个查找缺少事件的示例。 以下查询将返回其中某辆车已进入收费站,但在 15 分钟内未离开收费站的行。

SELECT I1.TollId, I1.EntryTime, I2.ExitTime, I1.LicensePlate, DATEDIFF(minute,I1.EntryTime,I2.ExitTime) AS DurationinMinutes   
FROM Input1 I1 TIMESTAMP BY EntryTime   
LEFT OUTER JOIN Input2 I2 TIMESTAMP BY ExitTime  
ON I1.TollId=I2.TollId  
AND I1.LicensePlate=I2.LicensePlate  
AND DATEDIFF( minute , I1 , I2 ) BETWEEN 0 AND 15   
WHERE I2.TollId IS NULL  
  

JOIN 的特殊 DATEDIFF 函数

语法

DATEDIFF ( datepart , input_source1, input_source2 )  

参数

dateparts

示例。 "second"、"millisecond"、"minute"等)

input_source1

联接中的第一个输入源。 在内部,会将与此 input_source 中的事件关联的时间戳传递给函数。

input_source2

联接中的第二个输入源。 在内部,会将与此 input_source 中的事件关联的时间戳传递给函数。

返回类型

返回从 input_source1 时间戳到 input_source2 时间戳所经历的 dateparts 中的单位数。 如果第二个列的时间戳大于第一个input_source返回的值可能为负。