使用PowerQuery

时间:2018-03-31 20:13:15

标签: json list record powerquery

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

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

数据

enter image description here

如您所见,数据包含与特定“种族”(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]不存在。

2 个答案:

答案 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" }
    ]}}

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

Start Table

此时,选择Expand to New Rows,然后展开id列,使您的表格如下所示:

Intermediate Table

此时,您可以应用@mccard建议的技巧。按第一列分组并在最后一次使用时聚合,例如,最大值

Group By

最后一步产生如下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(_)), ",")

无论哪种方式,你都应该这样做:

Final Table