作为我为团队创建的工具的一部分,我通过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>
我希望它的结构为:
10000,20000,30000
问题
当我在列表中选择“Extract values”时,我收到以下消息:
Expression.Error:我们无法将Record类型的值转换为type 文本。
如果我选择“展开到新行”,则会为每个唯一的驱动程序代码创建重复的行。我现在每个唯一的race_id有几行,但我想要的是每个唯一的race_id一行和一个连接的驱动程序代码列表。
我尝试了什么
我已尝试通过race_id对数据进行分组,但在对数据进行分组时允许的操作不包括连接行。
我也尝试过删除列,但这给我留下了同样的问题:我仍然有多行。
我已广泛搜索(和Stack Overflowed)这个问题而没有运气。可能是我使用了错误的关键字,所以如果存在重复,我会道歉。
更新:到目前为止我根据答案尝试了什么
我尝试了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}})
注意:如果我不写[driver_code][id]
而只写[id]
,那么我会收到另一个错误,指出列[id]
不存在。
答案 0 :(得分:1)
一种方法是使用高级编辑器,并在代码中直接对数据进行分组时更改操作。
首先,使用菜单中的可用操作之一创建分组。例如,创建一个列&#34; Sum&#34;使用Sum操作。它会产生错误,但我们应该开始使用起始代码。
然后,打开高级编辑器,找到与该操作对应的代码。它应该是这样的:
{{&#34; Sum&#34;,每个List.Sum([driver_codes]),输入文字}}
将其更改为:
{{&#34; driver_codes&#34;,每个Text.Combine([driver_codes],&#34;,&#34;),输入文字}}
答案 1 :(得分:1)
这里的JSON等同于您给出的XML示例:
{"race": {
"race_id": "ABC123445",
"begin_time": "2018-03-23T00:00:00Z",
"vehicle_id": "gokart_11",
"driver_code": [
{ "id": "90200" },
{ "id": "90500" }
]}}
如果将其加载到查询编辑器中,将其转换为表格,然后展开“值”记录,您将有一个如下所示的表:
此时,选择Expand to New Rows,然后展开id
列,使您的表格如下所示:
此时,您可以应用@mccard建议的技巧。按第一列分组并在最后一次使用时聚合,例如,最大值
最后一步产生如下M代码:
= Table.Group(#"Expanded driver_code1",
{"Name", "race_id", "begin_time", "vehicle_id"},
{{"id", each List.Max([id]), type text}})
而不是这样,您希望将List.Max
替换为Text.Combine
,如下所示:
= Table.Group(#"Changed Type",
{"Name", "race_id", "begin_time", "vehicle_id"},
{{"id", each Text.Combine([id], ","), type text}})
请注意,如果您的id
列不是文本格式,那么这将引发错误。要解决此问题,请在之前插入步骤,然后使用Transform Tab > Data Type: Text
对行进行分组以转换类型。另一个选择是在List.Transform
中使用Text.Combine
,如下所示:
Text.Combine(List.Transform([id], each Number.ToText(_)), ",")
无论哪种方式,你都应该这样做: