Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

To celebrate FabCon Vienna, we are offering 50% off select exams. Ends October 3rd. Request your discount now.

Reply
mkredpoint
Frequent Visitor

Help creating a table from some awkward api results - aka square pegs and round holes

Hi gang!

 

Newbie here - tasked with building a PowerBI custom connector to one of our APIs for loading some data. I have a lot of the pieces of the connector working (OAuth2, polling for job results using wait/for pattern), but when I get the final record set from the API, it's in a very unfriendly structure. Unfortunately, changing the API results is not an option, so I'm stuck with working with this format, which I need to manipulate into a Power Query table object. I've included a simplified version of the response payload below.

Essentially, we have a 'viewAttributes' array of records containing what I want to be the column names, and then a 'resultsRows' array of records that each has a 'values' array that corresponds to the values for the columns. These results can vary, but the number of values records will always line up with the # of column headers. So I want to dynamically create the following table. Is this doable using Power Query M language?

 

EducationGenderIncome
Graduate Degree likelyF$125,000-$149,999
Less than High School DiplomaM$25,000-$49,999
High School DiplomaUNKNOWN$50,000-$74,999

 

 

 

 

{
  "id": "abc123",
  "viewAttributes": [
    {
      "id": "69c07576-060f-448b-bd42-c365f8f46986",
      "name": "Education"
    },
    {
      "id": "7217d3ce-f6e8-4c3e-bd07-2cb8783043aa",
      "name": "Gender"
    },
    {
      "id": "90b4cea3-4d54-471a-9051-dac918af6252",
      "name": "Income"
    }
  ],
  "resultRows": [
    {
      "values": [
        {
          "id": "69c07576-060f-448b-bd42-c365f8f46986",
          "value": "Graduate Degree likely"
        },
        {
          "id": "7217d3ce-f6e8-4c3e-bd07-2cb8783043aa",
          "value": "F"
        },
        {
          "id": "90b4cea3-4d54-471a-9051-dac918af6252",
          "value": "$125,000-$149,999"
        }
      ]
    },
    {
      "values": [
        {
          "id": "69c07576-060f-448b-bd42-c365f8f46986",
          "value": "Less than High School Diploma Extremely likely"
        },
        {
          "id": "7217d3ce-f6e8-4c3e-bd07-2cb8783043aa",
          "value": "M"
        },
        {
          "id": "90b4cea3-4d54-471a-9051-dac918af6252",
          "value": "$25,000-$49,999"
        }
      ]
    },
    {
      "values": [
        {
          "id": "69c07576-060f-448b-bd42-c365f8f46986",
          "value": "High School Diploma likely"
        },
        {
          "id": "7217d3ce-f6e8-4c3e-bd07-2cb8783043aa",
          "value": "UNKNOWN"
        },
        {
          "id": "90b4cea3-4d54-471a-9051-dac918af6252",
          "value": "$50,000-$99,999"
        }
      ]
    }
  ]
}

 

 

 

 

1 ACCEPTED SOLUTION
AlexisOlson
Super User
Super User

Ugh. Power Query can parse JSON fine but there's still a good bit of work left to do (joining on id and pivoting).

 

Try this:

let
    JSON = "
    {
      ""id"": ""abc123"",
      ""viewAttributes"": [
        {
          ""id"": ""69c07576-060f-448b-bd42-c365f8f46986"",
          ""name"": ""Education""
        },
        {
          ""id"": ""7217d3ce-f6e8-4c3e-bd07-2cb8783043aa"",
          ""name"": ""Gender""
        },
        {
          ""id"": ""90b4cea3-4d54-471a-9051-dac918af6252"",
          ""name"": ""Income""
        }
      ],
      ""resultRows"": [
        {
          ""values"": [
            {
              ""id"": ""69c07576-060f-448b-bd42-c365f8f46986"",
              ""value"": ""Graduate Degree likely""
            },
            {
              ""id"": ""7217d3ce-f6e8-4c3e-bd07-2cb8783043aa"",
              ""value"": ""F""
            },
            {
              ""id"": ""90b4cea3-4d54-471a-9051-dac918af6252"",
              ""value"": ""$125,000-$149,999""
            }
          ]
        },
        {
          ""values"": [
            {
              ""id"": ""69c07576-060f-448b-bd42-c365f8f46986"",
              ""value"": ""Less than High School Diploma Extremely likely""
            },
            {
              ""id"": ""7217d3ce-f6e8-4c3e-bd07-2cb8783043aa"",
              ""value"": ""M""
            },
            {
              ""id"": ""90b4cea3-4d54-471a-9051-dac918af6252"",
              ""value"": ""$25,000-$49,999""
            }
          ]
        },
        {
          ""values"": [
            {
              ""id"": ""69c07576-060f-448b-bd42-c365f8f46986"",
              ""value"": ""High School Diploma likely""
            },
            {
              ""id"": ""7217d3ce-f6e8-4c3e-bd07-2cb8783043aa"",
              ""value"": ""UNKNOWN""
            },
            {
              ""id"": ""90b4cea3-4d54-471a-9051-dac918af6252"",
              ""value"": ""$50,000-$99,999""
            }
          ]
        }
      ]
    }
    ",
    #"Parsed JSON" = Json.Document(JSON),
    resultRows = List.Transform(#"Parsed JSON"[resultRows], each [values]),
    #"Converted to Table" = Table.FromList(resultRows, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Added Index" = Table.AddIndexColumn(#"Converted to Table", "Index", 1, 1, Int64.Type),
    #"Expanded Lists" = Table.ExpandListColumn(#"Added Index", "Column1"),
    #"Expanded Records" = Table.ExpandRecordColumn(#"Expanded Lists", "Column1", {"id", "value"}, {"id", "value"}),
    viewAttributes = Table.FromRecords(#"Parsed JSON"[viewAttributes]),
    #"Merged Queries" = Table.NestedJoin(viewAttributes, {"id"}, #"Expanded Records", {"id"}, "viewAttributes", JoinKind.LeftOuter),
    #"Expanded values" = Table.ExpandTableColumn(#"Merged Queries", "viewAttributes", {"value", "Index"}, {"value", "Index"}),
    #"Removed Columns" = Table.RemoveColumns(#"Expanded values",{"id"}),
    #"Pivoted Column" = Table.Pivot(#"Removed Columns", List.Distinct(#"Removed Columns"[name]), "name", "value"),
    #"Changed Type" = Table.TransformColumnTypes(#"Pivoted Column",{{"Index", Int64.Type}, {"Education", type text}, {"Gender", type text}, {"Income", type text}})
in
    #"Changed Type"

 

AlexisOlson_0-1675288200603.png

View solution in original post

2 REPLIES 2
AlexisOlson
Super User
Super User

Ugh. Power Query can parse JSON fine but there's still a good bit of work left to do (joining on id and pivoting).

 

Try this:

let
    JSON = "
    {
      ""id"": ""abc123"",
      ""viewAttributes"": [
        {
          ""id"": ""69c07576-060f-448b-bd42-c365f8f46986"",
          ""name"": ""Education""
        },
        {
          ""id"": ""7217d3ce-f6e8-4c3e-bd07-2cb8783043aa"",
          ""name"": ""Gender""
        },
        {
          ""id"": ""90b4cea3-4d54-471a-9051-dac918af6252"",
          ""name"": ""Income""
        }
      ],
      ""resultRows"": [
        {
          ""values"": [
            {
              ""id"": ""69c07576-060f-448b-bd42-c365f8f46986"",
              ""value"": ""Graduate Degree likely""
            },
            {
              ""id"": ""7217d3ce-f6e8-4c3e-bd07-2cb8783043aa"",
              ""value"": ""F""
            },
            {
              ""id"": ""90b4cea3-4d54-471a-9051-dac918af6252"",
              ""value"": ""$125,000-$149,999""
            }
          ]
        },
        {
          ""values"": [
            {
              ""id"": ""69c07576-060f-448b-bd42-c365f8f46986"",
              ""value"": ""Less than High School Diploma Extremely likely""
            },
            {
              ""id"": ""7217d3ce-f6e8-4c3e-bd07-2cb8783043aa"",
              ""value"": ""M""
            },
            {
              ""id"": ""90b4cea3-4d54-471a-9051-dac918af6252"",
              ""value"": ""$25,000-$49,999""
            }
          ]
        },
        {
          ""values"": [
            {
              ""id"": ""69c07576-060f-448b-bd42-c365f8f46986"",
              ""value"": ""High School Diploma likely""
            },
            {
              ""id"": ""7217d3ce-f6e8-4c3e-bd07-2cb8783043aa"",
              ""value"": ""UNKNOWN""
            },
            {
              ""id"": ""90b4cea3-4d54-471a-9051-dac918af6252"",
              ""value"": ""$50,000-$99,999""
            }
          ]
        }
      ]
    }
    ",
    #"Parsed JSON" = Json.Document(JSON),
    resultRows = List.Transform(#"Parsed JSON"[resultRows], each [values]),
    #"Converted to Table" = Table.FromList(resultRows, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"Added Index" = Table.AddIndexColumn(#"Converted to Table", "Index", 1, 1, Int64.Type),
    #"Expanded Lists" = Table.ExpandListColumn(#"Added Index", "Column1"),
    #"Expanded Records" = Table.ExpandRecordColumn(#"Expanded Lists", "Column1", {"id", "value"}, {"id", "value"}),
    viewAttributes = Table.FromRecords(#"Parsed JSON"[viewAttributes]),
    #"Merged Queries" = Table.NestedJoin(viewAttributes, {"id"}, #"Expanded Records", {"id"}, "viewAttributes", JoinKind.LeftOuter),
    #"Expanded values" = Table.ExpandTableColumn(#"Merged Queries", "viewAttributes", {"value", "Index"}, {"value", "Index"}),
    #"Removed Columns" = Table.RemoveColumns(#"Expanded values",{"id"}),
    #"Pivoted Column" = Table.Pivot(#"Removed Columns", List.Distinct(#"Removed Columns"[name]), "name", "value"),
    #"Changed Type" = Table.TransformColumnTypes(#"Pivoted Column",{{"Index", Int64.Type}, {"Education", type text}, {"Gender", type text}, {"Income", type text}})
in
    #"Changed Type"

 

AlexisOlson_0-1675288200603.png

Thanks - this is exactly what I needed. I hope you gain some satisfaction knowing that you saved an internet stranger hours of frustration and futile trial and error attempts.

Helpful resources

Announcements
Top Solution Authors
Top Kudoed Authors