使用PowerQuery从列表中的JSON记录中提取逗号分隔的值
作为我为团队创建的工具的一部分,我通过PowerQuery连接到一个内部web服务 web服务返回嵌套的JSON,我很难将JSON数据解析为我想要的格式。具体来说,我在将列中记录的内容提取到逗号分隔的列表时遇到问题 数据 如您所见,数据包含与特定“种族”(种族id)相关的详细信息。我想重点关注的是使用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
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你的精彩答案,但你必须接受。谢谢!