练习 - 使用 let 语句引入变量

已完成

我们已使用气象数据集聚合和可视化数据。 在这里,你将了解如何使用 let 语句来引入变量和组织复杂查询。

let 语句可用于将复杂表达式分解为多个部分、定义查询正文外部的常量以便于阅读,或定义一次变量并在查询中多次使用它。 可以使用 let 语句创建组织有序的复杂查询。 可以使用多个 let 语句;每个语句必须后跟分号 (;)。

let 语句可用于不同类型的情况。 在最简单的级别,可以定义稍后将在查询中引用的标量值,例如 int、字符串、日期/时间或任何其他值。 可以创建将用作查询的表格输入的表的表格筛选视图。 还可以使用 let 语句创建函数。

使用 let 语句定义标量

回顾一下,以前的查询已根据位置或最小损坏进行筛选。 让我们使用查询开头的 let 语句定义这些边界值。

以下查询使用两个 let 语句来定义稍后将用作查询中的输入参数的标量值。 第一个定义值是数字,第二个是字符串。 let 语句以分号结尾。

请注意以双正斜杠 (//) 开头的查询中已注释掉的部分。 双正斜杠表示从注释的开头到行的末尾。 这些是运行查询时忽略的注释。

  1. 运行以下查询:

    运行查询

    let MinDamage = 1; // int
    let EventLocation = "ARIZONA"; // string
    StormEvents
    | where State == EventLocation
    | where DamageCrops + DamageProperty >= MinDamage
    | summarize Damage=round(avg(DamageProperty + DamageCrops)) by EventType
    | sort by Damage
    

    应获得如下图所示的结果:

    Screenshot of query using the let statement and its results.

  2. 尝试更改状态名称或最小损坏数并重新运行查询。 结果如何更改?

let 语句中使用 toscalar 将表格结果转换为标量值

接下来,让我们将最常见的事件类型计数视为时间函数。 首先,需要确定哪个是最常用的事件类型。 然后,你将在查询中使用此值。 使用 StormEvents 表通过计算每种类型中的事件数来查找排名靠前的 EventType。 使用 project 运算符仅返回 EventType 列。

在开始构造 let 语句之前,运行查询来找出此事件的实际含义。 这样,你便可以验证查询是否生成预期的结果。

运行查询

StormEvents
| summarize count() by EventType
| top 1 by count_
| project EventType

应获得如下图所示的结果:

Screenshot of preview of let query using complicated scalar and results.

你会注意到,查询生成了包含一列和一行的表格结果。 但是,需要将此值转换为标量值,以用作主查询中的筛选器值。 首先,定义要引入为 MostFrequentEventType 的变量名称。 接下来,需要通过将整个查询放入 toscalar() 函数中来将表格结果转换为标量值。

以下 let 语句总结了上述步骤:

let MostFrequentEventType = toscalar(
    StormEvents
    | summarize count() by EventType
    | top 1 by count_
    | project EventType);

请注意,此语句本身不是有效的查询,因为有效的查询必须至少包含一个不是 let 语句的语句。 但是,可以在查询中使用此存储标量值。 回顾一下,你想要将最常用的事件时间计数视为时间函数。 你将根据 MostFrequentEventType 进行筛选,然后按特定时间箱汇总计数。

在本例中,我们来看看每月的结果。 你将使用 startofmonth() 函数,该函数返回表示给定日期值的月份开始的日期时间。 在此查询中,你会将 StartTime 列用作 startofmonth() 函数的输入。

最后,将结果呈现为柱形图,以获取按月份装箱的最常用事件类型的计数的直方图。

  1. 运行以下查询:

    运行查询

    let MostFrequentEventType = toscalar(
        StormEvents
        | summarize count() by EventType
        | top 1 by count_
        | project EventType);
    StormEvents
    | where EventType == MostFrequentEventType
    | summarize count() by startofmonth(StartTime)
    | render columnchart
    

    应获得如下图所示的结果:

    Screenshot of let query using complicated scalar and results.

  2. 尝试更改查询以显示按月份装箱的最不常用事件类型的直方图并重新运行查询。

使用表格输出构造 let 语句

前面的示例创建了要用作查询中的输入参数的存储标量值。 但是,也可以使用 let 语句创建随后用作查询的输入的表格数据。

  1. 根据间接或直接导致死亡的事件筛选 StormEvents 表。 然后,使用 project 运算符返回列的子集。 此语句提供名为 KillerStorms 的表格输出。 将此 let 语句用作查询的起始输入。

    let KillerStorms =
        StormEvents
        | where DeathsDirect + DeathsIndirect > 0
        | project State, EventType, Deaths=DeathsDirect + DeathsIndirect;
    
  2. 然后,可以使用之前的单元中了解的一些聚合函数。 运行以下查询:

    运行查询

    let KillerStorms =
        StormEvents
        | where DeathsDirect + DeathsIndirect > 0
        | project State, EventType, Deaths=DeathsDirect + DeathsIndirect;
    KillerStorms
    | summarize DistinctKillerEventTypes=dcount(EventType), TotalDeaths=sum(Deaths) by State
    | sort by TotalDeaths
    

    应获得如下图所示的结果:

    Screenshot of tabular let statement and results.

  3. 查看结果。 DistinctKillerEventTypes 列中汇总的所有事件是否都称为“killer storms”?

使用 let 语句创建用户定义的函数

还可以使用 let 语句定义用户定义的函数,这些函数是可重用的子查询。 假设你想要弄清楚每个事件类型造成损坏的百分比。 你将创建用于计算百分比的用户定义的函数,稍后调用此函数并指定要用于计算百分比的列。

let 语句中,你将使用以下常规语法声明函数名称、参数和正文:

let function=(argument1:datatype, argument2:datatype) {functionbody};

具体而言,你将使用用户定义的函数来计算百分比。 首先,定义数据类型和输入参数。 对于此示例,你将使用以下参数:

参数名称 数据类型 说明
部分 real 要计算其百分比的总事件部分。
total real 事件的总数。

你将使用 round() 函数将答案舍入为包含两位小数。

总而言之,let 语句描述的用户定义的函数为:

let Pcent = (portion:real, total:real){round(100 * portion / total, 2)};
  1. 在以下查询中使用此 let 语句:

    运行查询

    let Pcent = (portion: real, total: real) { round(100 * portion / total, 2) };
    StormEvents
    | extend Damage = DamageCrops + DamageProperty
    | summarize TotalEvents = count(), TotalDamagingEvents = countif(Damage > 0) by EventType
    | project EventType, TotalDamagingEvents, TotalEvents, Percentage = Pcent(TotalDamagingEvents, TotalEvents)
    | sort by EventType asc
    

    应获得如下图所示的结果:

    Screenshot of let statement with results.

  2. 请花点时间了解结果。 尝试修改查询,以按损坏类型显示百分比的细分并重新运行查询。

查看结果。 百分比的含义是什么? 请注意,查询调用我们在 let 语句中定义的 Pcent 函数。 此函数中使用的输入是 TotalDamagingEvents 和 TotalEvents,这意味着你要查找导致损坏的事件百分比。