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

使用PowerQuery从列表中的JSON记录中提取逗号分隔的值,json,list,record,powerquery,Json,List,Record,Powerquery,作为我为团队创建的工具的一部分,我通过PowerQuery连接到一个内部web服务 web服务返回嵌套的JSON,我很难将JSON数据解析为我想要的格式。具体来说,我在将列中记录的内容提取到逗号分隔的列表时遇到问题 数据 如您所见,数据包含与特定“种族”(种族id)相关的详细信息。我想重点关注的是driver\u code中的信息,这是一个记录列表。记录的数量从0到4不等,每条记录的结构为id:50000(50000可以是任意5位数字)。因此可能是: id:10000 身份证号码:20000

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

web服务返回嵌套的JSON,我很难将JSON数据解析为我想要的格式。具体来说,我在将列中记录的内容提取到逗号分隔的列表时遇到问题

数据

如您所见,数据包含与特定“种族”(种族id)相关的详细信息。我想重点关注的是
driver\u code
中的信息,这是一个记录列表。记录的数量从0到4不等,每条记录的结构为
id:50000
(50000可以是任意5位数字)。因此可能是:

id:10000
身份证号码: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>
问题

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

表达式.错误:无法将类型为Record的值转换为类型 文本

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

我尝试过的

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

我还尝试取消激活该列,但这给我留下了相同的问题:我仍然会得到多行

我在谷歌上搜索了这个问题,但运气不好。但是,可能是我使用了错误的关键字,因此如果存在重复的关键字,我深表歉意

更新:根据到目前为止的答案,我尝试了什么

我尝试了亚历克西斯·奥尔森(Alexis Olson)的优秀且非常详细的方法,但最终出现以下错误:

表达式。错误:无法将值“id”转换为类型Number。详情:

值=id 类型=类型

错误源于使用以下任意一行M代码(一行带有List.Transform,另一行没有):


注意:如果我不写
[driver\u code][id]
,而只写
[id]
,那么我会收到另一个错误,即
[id]
列不存在

一种方法是使用高级编辑器,并在代码中直接分组数据时更改操作

首先,使用菜单中可用的操作之一创建分组。例如,使用Sum操作创建一列“Sum”。它将给出一个错误,但是我们应该得到开始代码来处理

然后,打开高级编辑器并找到与该操作对应的代码。应该是这样的:

{{“Sum”,每个List.Sum([driver_code]),键入text}

将其更改为:


{{“driver_code”,每个文本。组合([driver_code],“,”),键入Text}}

以下是与您给出的XML示例等效的JSON:

{"race": {
    "race_id": "ABC123445",
    "begin_time": "2018-03-23T00:00:00Z",
    "vehicle_id": "gokart_11",
    "driver_code": [
      { "id": "90200" },
      { "id": "90500" }
    ]}}
如果将其加载到查询编辑器中,将其转换为一个表,并展开值记录,您将得到一个如下所示的表:

= Table.Group(#"Expanded driver_code1",
              {"Name", "race_id", "begin_time", "vehicle_id"},
              {{"id", each List.Max([id]), type text}})
Text.Combine(List.Transform([id], each Number.ToText(_)), ",")

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

= Table.Group(#"Expanded driver_code1",
              {"Name", "race_id", "begin_time", "vehicle_id"},
              {{"id", each List.Max([id]), type text}})
Text.Combine(List.Transform([id], each Number.ToText(_)), ",")

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

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

= Table.Group(#"Expanded driver_code1",
              {"Name", "race_id", "begin_time", "vehicle_id"},
              {{"id", each List.Max([id]), type text}})
Text.Combine(List.Transform([id], each Number.ToText(_)), ",")
与此相反,您希望将
List.Max
替换为
Text。按如下方式组合

= Table.Group(#"Changed Type",
              {"Name", "race_id", "begin_time", "vehicle_id"},
              {{"id", each Text.Combine([id], ","), type text}})
请注意,如果您的
id
列不是文本格式,则会引发错误。要解决此问题,请在使用
Transform Tab>Data-Type:Text
对行进行分组之前插入一个步骤以转换类型。另一个选项是使用
列表。在
文本中变换
。如下组合

= Table.Group(#"Expanded driver_code1",
              {"Name", "race_id", "begin_time", "vehicle_id"},
              {{"id", each List.Max([id]), type text}})
Text.Combine(List.Transform([id], each Number.ToText(_)), ",")
无论哪种方式,您都应该以以下方式结束:


我很难再现您的错误。您可以提供一个示例JSON字符串来尝试使用它吗。请看我的编辑。这对你来说更清楚了吗?当然。这是XML,不是JSON。谢谢你看这个。我尝试了您的解决方案,但出现了错误“Expression.error:无法将List类型的值转换为Text类型。详细信息:value=List type=type”。也许这与JSON的结构有关。我在我的问题中补充了这一点。你能看一看,看看这是否有区别吗?亚历克西斯·奥尔森似乎在他的回答中,在他上次的指示中,提到了这个新问题。我已经编辑了我的问题,以包括基于你回答的结果。你能看一下吗?您的代码看起来确实是正确的方法,但我仍然会遇到一个类似于我以前遇到的错误。您似乎跳过了将
driver\u code
扩展到
id
列的步骤。在进行分组之前,请检查您的表是否与我的第二张图像相似。Ahhh。当然现在我展开了这个列,它工作得非常好。我希望我有足够的代表+1你的精彩答案,但你必须接受。谢谢!