✅ Azure 流分析 ✅ 构造事件流
与标准 T-SQL 一样,Azure 流分析查询语言中的 JOIN 用于合并来自两个或多个输入源的记录。 Azure 流分析中的 JOIN 本质上是临时性的,这意味着每个 JOIN 必须提供一些限制,说明匹配行可以按时间分隔的距离。 例如,说“在相同的 LicensePlate 和 TollId 上发生 TollBoothExit 事件时,将 TollBoothEntry 事件加入到 TollBoothEntry 事件中,并在彼此的 5 分钟内相互发生”是合法的:但是,“在 LicensePlate 和 TollId 上发生 TollBoothExit 事件时加入 TollBoothEntry 事件”不是 - 它将每个 TollBoothEntry 与所有 TollBoothExit 的无限集合匹配到相同的 LicensePlate 和 TollId。
使用 DATEDIFF 函数在 JOIN 的 ON 子句中指定关系的时间边界。 最大 DATEDIFF 大小为 7 天。 有关其常规用途的详细信息,请参阅 DATEDIFF。 在 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 谓词必须包含与两个源的分区键匹配的条件。
[ LEFT OUTER JOIN ]
指定在结果集中包括左表中所有不满足联接条件的行,除了由内部联接返回所有的行之外,还将另外一个表的输出列设置为 NULL。
ON <join_condition>
指定联接所基于的条件。 联接条件必须具有为关系定义的时间限制或临时摇摆空间,并在 JOIN 的 ON 子句内指定,使用特殊 DATEDIFF 函数的 JOIN 函数语法指定。
例子
在 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 使用常规语法,其中日期/时间列或表达式作为第二个和第三个参数传入。 但是,当 DATEDIFF 函数在 JOIN 条件中使用时,将使用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”、“毫秒”、“minute”等)
input_source1
Join 中的第一个输入源。 在内部,与此input_source事件关联的时间戳将传递到函数中。
input_source2
Join 中的第二个输入源。 在内部,与此input_source事件关联的时间戳将传递到函数中。
返回类型
返回从input_source1时间戳到input_source2时间戳的日期部分的单位数。 如果第二个input_source的时间戳大于第一个时间戳,则返回的值可以是负值。