使用 PowerQuery 从列表中的 JSON 记录中提取逗号分隔值

Gro*_*rop 2 json list record powerquery

作为我为团队创建的工具的一部分,我通过 PowerQuery 连接到内部 Web 服务。

Web 服务返回嵌套的 JSON,但我无法将 JSON 数据解析为我正在寻找的格式。具体来说,我在将列中的记录内容提取到逗号分隔列表时遇到问题。

数据

在此输入图像描述

正如您所看到的,数据包含与特定“种族”相关的详细信息 ( race_id)。driver_codes我想关注的是记录列表中的信息。记录数量从 0 到 4 不等,每条记录的结构为id: 50000(50000 可以是任何 5 位数字)。所以它可能是:

id: 10000 id: 20000 id: 30000

根据要求,原始 JSON 的示例片段:

<race>
    <race_id>ABC123445</race_id>
    <begin_time>2018-03-23T00:00:00Z</begin_time>
    <vehicle_id>gokart_11</vehicle_id>
    <driver_code>
        <id>90200</id>
    </driver_code> 
    <driver_code>
        <id>90500</id>
    </driver_code>
</race>
Run Code Online (Sandbox Code Playgroud)

我希望它的结构如下:

10000,20000,30000
Run Code Online (Sandbox Code Playgroud)

问题

当我在列表列上选择“提取值”时,我收到以下消息:

Expression.Error:我们无法将 Record 类型的值转换为 Text 类型。

如果我选择“扩展到新行”,则会为每个唯一的驱动程序代码创建重复的行。我现在每个唯一的race_id 有几行,但我想要的是每个唯一的race_id 一行和驱动程序代码的串联列表。

我尝试过的

我尝试过按race_id 对数据进行分组,但分组数据时允许的操作不包括连接行。

我也尝试过取消旋转该列,但这给我带来了同样的问题:我仍然得到多行。

我已经用谷歌搜索了(并且堆栈溢出)这个问题,但没有运气。然而,我可能使用了错误的关键字,所以如果存在重复的关键字,我深表歉意。

更新:到目前为止我根据答案尝试过的内容

我尝试了 Alexis Olson 的出色且非常详细的方法,但最终出现以下错误:

Expression.Error:我们无法将值“id”转换为 Number 类型。细节:

值=id 类型=类型

该错误来自于使用以下任一 M 代码行(一行带有 List.Transform,另一行不带):

= Table.Group(#"Renamed Columns", {"race_id", "begin_time", "vehicle_id"},
 {{"DriverCodes", each Text.Combine([driver_code][id], ","), type text}})
= Table.Group(#"Renamed Columns", {"race_id", "begin_time", "vehicle_id"},
 {{"DriverCodes", each Text.Combine(List.Transform([driver_code][id], each Number.ToText(_)), ","), type text}})
Run Code Online (Sandbox Code Playgroud)

注意:如果我不写[driver_code][id],但只有[id]那时我会收到另一个错误,指出该列[id]不存在。

Ale*_*son 5

以下是与您提供的 XML 示例等效的 JSON:

{"race": {
    "race_id": "ABC123445",
    "begin_time": "2018-03-23T00:00:00Z",
    "vehicle_id": "gokart_11",
    "driver_code": [
      { "id": "90200" },
      { "id": "90500" }
    ]}}
Run Code Online (Sandbox Code Playgroud)

如果将其加载到查询编辑器中,将其转换为表,然后展开值记录,您将得到一个如下所示的表:

起始表

此时,选择“展开到新行”,然后展开该id列,使表如下所示:

中间表

此时,您可以应用 @mccard 建议的技巧。按第一列分组并使用 max 等对最后一列进行聚合。

通过...分组

最后一步生成如下 M 代码:

= Table.Group(#"Expanded driver_code1",
              {"Name", "race_id", "begin_time", "vehicle_id"},
              {{"id", each List.Max([id]), type text}})
Run Code Online (Sandbox Code Playgroud)

相反,您希望替换List.MaxText.Combine如下所示:

= Table.Group(#"Changed Type",
              {"Name", "race_id", "begin_time", "vehicle_id"},
              {{"id", each Text.Combine([id], ","), type text}})
Run Code Online (Sandbox Code Playgroud)

请注意,如果您的id列不是文本格式,那么这将引发错误。要解决此问题,请在使用转换类型对行进行分组之前插入一个步骤。另一种选择是在你的内部Transform Tab > Data Type: Text使用,如下所示:List.TransformText.Combine

Text.Combine(List.Transform([id], each Number.ToText(_)), ",")
Run Code Online (Sandbox Code Playgroud)

不管怎样,你最终应该得到这样的结果:

决赛桌