练习 - 使用联接运算符合并表结果

已完成

本练习介绍如何使用 join 运算符。 回想一下,join 运算符通过匹配每个表中指定列的值来合并两个表的行。

让我们使用 join 运算符的结果来回答有关销售额的问题。

使用 join 运算符

在本零售公司方案中,团队要求你列出销售额最高的三个国家/地区。

开始检查 SalesFact 表时,你注意到 SalesAmount 列中提供了你需要的数据,但该表不包含任何国家/地区数据。 检查其他表时,你注意到 Customers 表的 RegionCountryName 列中提供了国家/地区数据。 你还注意到,这两个表都包含 CustomerKey 列。

由于数据分布在两个表中,因此你同时需要客户数据和销售数据,才能编写提供所请求信息的查询。 若要编写查询,请使用 join 运算符和 CustomerKey 列来匹配这两个表中的行。

现在就可以编写查询了。 使用 innerjoin 从这两个表中获取所有匹配的行。 为了获得最佳性能,使用客户维度表作为左表,使用销售事实数据表作为右表。

在以下过程中,你将分阶段生成查询,以便更好地了解使用 join 运算符的结果。

  1. 运行以下查询,从 Customers 表和 SalesFact 表中获取 10 个匹配的任意行。

    运行查询

    Customers
    | join kind=inner SalesFact on CustomerKey
    | take 10
    

    查看生成的列表。 请注意,表包含 Customers 表中的列,后跟 SalesFact 表中的匹配列。

  2. 运行以下查询来汇总联接表,以获取销售额最高的三个国家/地区。

    运行查询

    Customers
    | join kind=inner SalesFact on CustomerKey
    | summarize TotalAmount = round(sum(SalesAmount)) by RegionCountryName
    | top 3 by TotalAmount
    

    结果应如下图所示:

    Screenshot of the join operator query, showing the top three countries/regions by sales.

  3. 查看生成的列表。 尝试修改查询,以同时显示这些国家/地区的相应总成本和利润。

然后,团队要求按月份确定上一记录年份中收入最低的国家/地区。 若要获取此数据,请使用类似的查询。 但这次,使用 startofmonth() 函数来简化按月分组。 你还将使用 arg_min() 聚合函数来查找每个月收入最低的国家/地区。

  1. 运行以下查询。

    运行查询

    Customers
    | join kind=inner SalesFact on CustomerKey
    | summarize TotalAmount = round(sum(SalesAmount))
        by Month = startofmonth(DateKey), RegionCountryName
    | summarize arg_min(TotalAmount, RegionCountryName) by Month
    | top 12 by Month desc
    

    结果应如下图所示:

    Screenshot of the join operator query, showing the countries/regions with the lowest revenues.

  2. 查看每一行。 请注意,第一列为去年的月份(按降序显示),后跟显示当月销售额最低的国家/地区的总销售额的列。

使用 rightouter join 类型

你的销售团队希望按产品类别了解总销售额。 开始查看可用数据时,你意识到需要 Products 表来获取产品类别列表,需要 SalesFact 表来获取销售数据。 你还意识到,需要计算每个类别的销售额,并列出所有产品类别。

对请求进行分析之后,你选择使用 rightouterjoin,因为它可以返回右表中的所有销售记录,其中包括左表中的匹配数据产品类别。 编写查询时,你使用 Products 表作为左维度表,匹配 SalesFact 事实数据表中的数据并按产品类别对结果进行分组

  1. 运行以下查询。

    运行查询

    Products
    | join kind=rightouter SalesFact on ProductKey
    | summarize TotalSales = count() by ProductCategoryName
    | order by TotalSales desc
    

    结果应如下图所示:

    Screenshot of the join operator query, showing the total sales per product.

  2. 请注意,执行时间为 0.834 秒,不过,此时间可能因运行而异。 此查询是获取此答案的一种方法,并且是未针对性能进行优化的一个很好的查询示例。 稍后,可使用 lookup 运算符将此时间与等效查询的执行时间进行比较,该运算符针对此类数据进行了优化。

使用 rightanti join 类型

同样,你的销售团队希望了解每个产品类别中未销售的产品数量。 你可使用 rightantijoin 来获取 Products 表中与 SalesFacts 表中的任何行不匹配的所有行,然后按产品类别对结果进行分组。

  1. 运行以下查询。

    运行查询

    SalesFact
    | join kind=rightanti Products on ProductKey
    | summarize Count = count() by ProductCategoryName
    | order by Count desc
    

    结果应如下图所示:

    Screenshot of the join operator query, showing the number of products that don't sell in each product category.

    查看每一行。 结果显示每个产品类别未售出的产品数。 请注意,rightanti join 仅选择没有销售事实的产品,指示 join 运算符返回的产品没有销售额。