Forum Discussion

Erika's avatar
Erika
New Member
1 year ago
Solved

Finding All Recursive Connections in a Relationship Table

Hi,

I'm working in Power BI with a table that represents relationships between elements. Each row contains an ID and a ToID, indicating that one element is linked to another.

Here is an example of my table:

ID (Table_Relations) ToID (Table_Relations)

BG0012BG0011
BG0012BG0005
BG0005BG0007
BG0005BG0010
BG0011BG0010

Goal:

I want to create a new table that displays all direct and indirect connections, starting from an ID and finding all elements connected to it (including transitively).

The expected output is:

IDReferencia ConnectedID

BG0012BG0012
BG0005BG0012
BG0011BG0012
BG0007BG0012
BG0010BG0012
BG0012BG0005
BG0005BG0005
BG0007BG0005
BG0010BG0005
BG0012BG0011
BG0011BG0011
BG0010BG0011

 

The idea is to use the ConnectedID to filter a Sankey chart so that it shows all connections and doesn't stop at the first level, but i'm having problems with dax formula or powerquery formula.

 

Is it the best way? Are there any efficient alternatives? 

  • To solve the recursive relationship mapping problem in Power BI, we can use Power Query to build a function that iterates through the relationships table and recursively finds all connected IDs for each starting ID, both direct and indirect. This can be done by first defining a custom recursive function that identifies all direct connections for a given ID, then recursively retrieving all connected IDs for each of those direct connections. Once the function is set up, we apply it to each row in the relationship table, generating a new column that contains all connected IDs. We then expand this list into individual rows, ensuring that each connection is represented separately. Finally, we filter out cases where the ID is the same as the connected ID and load the transformed data into Power BI for further analysis, such as visualizing connections in a Sankey chart.

    Here's the full Power Query M code to achieve this:

    let
        // Function to find all related IDs recursively
        GetConnectedIDs = (startID as text, relationsTable as table) =>
        let
            // Get the direct connections for the startID
            DirectConnections = Table.SelectRows(relationsTable, each [ID] = startID),
            // Extract the ToIDs from the DirectConnections
            DirectToIDs = DirectConnections[ToID],
            // Recursively get connected IDs from those direct ToIDs
            RecursiveConnections = List.Transform(DirectToIDs, each GetConnectedIDs(_, relationsTable)),
            // Combine the direct and recursive connections
            AllConnections = List.Distinct(DirectToIDs & List.Combine(RecursiveConnections))
        in
            AllConnections,
    
        // Load the original relationships table
        Source = Table_Relations,
        
        // Add a column that applies the recursive function to each ID
        AddConnectedIDsColumn = Table.AddColumn(Source, "ConnectedIDs", each GetConnectedIDs([ID], Source)),
        
        // Expand the list of connected IDs into individual rows
        ExpandConnectedIDs = Table.ExpandListColumn(AddConnectedIDsColumn, "ConnectedIDs"),
        
        // Filter out rows where the ID equals the ConnectedID
        FilteredRows = Table.SelectRows(ExpandConnectedIDs, each [ID] <> [ConnectedIDs])
    in
        FilteredRows
    

     This query will generate a table with all connected IDs for each starting ID, excluding the ID itself, and ready for use in visualizations like Sankey charts.

3 Replies

  • Hi Erika ,
    In Power BI, achieving a recursive relationship mapping like this can be challenging due to DAX's limitations with recursion. The best approach is to use Power Query (M Language) to iteratively expand connections and generate the desired output table.

    You can create a recursive function in Power Query to traverse the relationships and build a table with all direct and indirect connections, ensuring that every linked element is included transitively. Alternatively, if your dataset is large and performance is a concern, using a Python script in Power BI to handle the recursion more efficiently before loading the data might be a better option.

    While DAX alone isn’t well-suited for recursion, you can leverage path functions like PATH() and LOOKUPVALUE() to establish hierarchical relationships if the dataset structure allows it. The ideal solution depends on data size and complexity, but Power Query remains the most efficient method for handling recursive relationships in this scenario.

  • Erika's avatar
    Erika
    New Member

    Hi rohit1991, thank for you answer. I tried with Power Query... but I wasn't able to construct the table. Could you help me?

    • rohit1991's avatar
      rohit1991
      Super User

      To solve the recursive relationship mapping problem in Power BI, we can use Power Query to build a function that iterates through the relationships table and recursively finds all connected IDs for each starting ID, both direct and indirect. This can be done by first defining a custom recursive function that identifies all direct connections for a given ID, then recursively retrieving all connected IDs for each of those direct connections. Once the function is set up, we apply it to each row in the relationship table, generating a new column that contains all connected IDs. We then expand this list into individual rows, ensuring that each connection is represented separately. Finally, we filter out cases where the ID is the same as the connected ID and load the transformed data into Power BI for further analysis, such as visualizing connections in a Sankey chart.

      Here's the full Power Query M code to achieve this:

      let
          // Function to find all related IDs recursively
          GetConnectedIDs = (startID as text, relationsTable as table) =>
          let
              // Get the direct connections for the startID
              DirectConnections = Table.SelectRows(relationsTable, each [ID] = startID),
              // Extract the ToIDs from the DirectConnections
              DirectToIDs = DirectConnections[ToID],
              // Recursively get connected IDs from those direct ToIDs
              RecursiveConnections = List.Transform(DirectToIDs, each GetConnectedIDs(_, relationsTable)),
              // Combine the direct and recursive connections
              AllConnections = List.Distinct(DirectToIDs & List.Combine(RecursiveConnections))
          in
              AllConnections,
      
          // Load the original relationships table
          Source = Table_Relations,
          
          // Add a column that applies the recursive function to each ID
          AddConnectedIDsColumn = Table.AddColumn(Source, "ConnectedIDs", each GetConnectedIDs([ID], Source)),
          
          // Expand the list of connected IDs into individual rows
          ExpandConnectedIDs = Table.ExpandListColumn(AddConnectedIDsColumn, "ConnectedIDs"),
          
          // Filter out rows where the ID equals the ConnectedID
          FilteredRows = Table.SelectRows(ExpandConnectedIDs, each [ID] <> [ConnectedIDs])
      in
          FilteredRows
      

       This query will generate a table with all connected IDs for each starting ID, excluding the ID itself, and ready for use in visualizations like Sankey charts.