从 JSON 子对象数组中提取 属性 到列中以逗号分隔的值

Extract property from JSON child object array into a comma-delimited value in a column

我有一个固定深度的分层 JSON 对象数组,我想使用 PowerQuery 将其作为 table 导入 Excel.

这是一个示例,代表了我能够成功达到的程度:

let
    json = "[
    {
      ""t"": {
        ""a"": {
          ""p"": [
            {
              ""id"": ""5z1V"",
              ""name"": ""p-First"",
              ""type"": ""p""
            }
          ],
          ""id"": ""2aXp"",
          ""name"": ""a-un""
        },
        ""p"": [
          {
            ""id"": ""5z1V"",
            ""name"": ""p-First"",
            ""type"": ""p""
          },
          {
            ""id"": ""3BDN"",
            ""name"": ""p-Second"",
            ""type"": ""p""
          }
        ],
        ""id"": ""6Goh"",
        ""name"": ""t-Primary""
      }
    },
    {
      ""t"": {
        ""a"": {
          ""p"": [
            {
              ""href"": ""https://api.example.com/v1/p/1Gxk"",
              ""id"": ""1Gxk"",
              ""name"": ""p-Third"",
              ""type"": ""p"",
              ""uri"": ""p:1Gxk""
            }
          ],
          ""id"": ""3CKV"",
          ""name"": ""a-deux""
        },
        ""p"": [
          {
            ""id"": ""1Gxk"",
            ""name"": ""p-Third"",
            ""type"": ""p""
          }
        ],
        ""id"": ""0lLd"",
        ""name"": ""t-Secondary""
      }
    }
]",
    Source = Json.Document(json),
    #"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"t"}, {"t"}),
    #"Expanded t" = Table.ExpandRecordColumn(#"Expanded Column1", "t", {"a", "p", "id", "name"}, {"t.a", "t.p", "t.id", "t.name"}),
    #"Expanded t.a" = Table.ExpandRecordColumn(#"Expanded t", "t.a", {"p", "id", "name"}, {"t.a.p", "t.a.id", "t.a.name"})
in
    #"Expanded t.a"

然而,这只会给我一个 table 这样的:

t.a.p t.a.id t.a.name t.p t.id t.name
[List] 2aXp a-un [List] 6Goh t-Primary
[List] 3CKV a-deux [List] 0lLd t-Secondary

我想要的是将那些 [List] 值扩展为来自“p”对象的“名称”属性 的逗号分隔值(所有“p”对象都是同一类型, 虽然有些“p”对象是“a”对象的子对象,有些“p”对象是“t”对象的子对象。

当我尝试扩展 t.a.p 列或 t.p 列时,我有两个选择:

  1. 扩展到新行:捕获所有“p”属性并创建新行,当存在多个“p”对象时,这是一个问题。我只想保留“p”对象的“名称”属性。
  2. Expant Values...:为每一行生成错误:“Expression.Error:我们无法将 Record 类型的值转换为 Text 类型。”。查询中有问题的行是:
= Table.TransformColumns(#"Expanded t.a", {"t.a.p", each Text.Combine(List.Transform(_, Text.From), ","), type text})

最终结果应该是这样的:

t.a.p t.a.id t.a.name t.p t.id t.name
p-First 2aXp a-un p-First, p-Second 6Goh t-Primary
p-Third 3CKV a-deux p-Third 0lLd t-Secondary

如果有帮助,每个“a”对象中总是有一个或多个“p”对象,每个“t”对象中总是有一个或多个“p”对象。 “p”对象无论在“a”还是“t”对象中都具有相同的模式。

你非常接近。问题是这些列是记录列表,您想要专门提取 name 记录。因此,您可以使用函数 each [name].

,而不是对记录没有意义的 Text.From
= Table.TransformColumns(
      #"Expanded t.a", 
      {"t.p", each Text.Combine(List.Transform(_, each [name]), ", "), type text}
  )

each 语法在这里可能有点混乱,所以如果您愿意,可以使用带有 () => 的函数式语法来编写它。即

= Table.TransformColumns(
      #"Expanded t.a", 
      {"t.p", (C) => Text.Combine(List.Transform(C, (R) => R[name]), ", "), type text}
  )

我选择 C 作为列的变量名称,并选择 R 作为记录。