JOIN(Azure 流分析)
与标准的 T-SQL 一样,Azure 流分析查询语言中的 JOIN 用于组合两个或更多个输入源中的记录。 Azure 流分析中的 JOIN 在性质上是短暂的,也就是说,每个 JOIN 必须对匹配行的分离时限施加某种限制。 例如,说“当 TollBoothEntry 事件在同一 LicensePlate 和 TollId 上发生且彼此相传 5 分钟内时,将 TollBoothEntry 事件与 TollBoothExit 事件联接”是合法的:但“当 TollBoothExit 事件在 LicensePlate 和 TollId 上发生时,将 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 外部联接。 对于内部联接,仅当找到匹配时返回结果。 但是对于 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的时间戳大于第一个时间戳,则返回的值可以为负值。