Forum Discussion

nchamilton2's avatar
nchamilton2
Frequent Visitor
1 year ago
Solved

DateSpan

Good afternoon, I have a datespan table that I'm trying incorporate into my model. I have my fact table, Phases, Datespan and Projects.   I'm trying to avoid the many to many relationship so I can...
  • Anonymous's avatar
    Anonymous
    1 year ago

    Hi nchamilton2 ,

     

    You're correct that directly joining the DateSpan table to the FactTable introduces a many-to-many relationship, which Power BI doesn’t handle as cleanly as other analytics tools. To support your scenario generating all dates between each phase’s estimated start and end, while avoiding many-to-many joins the recommended approach is to reshape the model slightly by introducing Phases as a bridge table.

     

    First create a dynamic DateSpan table in Power Query that expands each phase into one row per date using this code:

    let
        Source = Phases,
        ChangedTypes = Table.TransformColumns(Source, {
            {"EstStartDate", each Date.FromText(_, "en-US"), type date},
            {"EstEndDate", each Date.FromText(_, "en-US"), type date}
        }),
        AddDateList = Table.AddColumn(ChangedTypes, "Date", each List.Dates([EstStartDate], Duration.Days([EstEndDate] - [EstStartDate]) + 1, #duration(1,0,0,0))),
        ExpandedDates = Table.ExpandListColumn(AddDateList, "Date"),
        SelectedColumns = Table.SelectColumns(ExpandedDates, {"PhaseId", "Date", "PhaseName"})
    in
        SelectedColumns

    Adjust the relationships in the model:

    • DynamicDateSpan[PhaseId] → Phases[PhaseId] (One-to-many)
    • FactTable[PhaseId] → Phases[PhaseId] (Many-to-one)
    • FactTable[ProjectID] → Projects[ProjectID] (Many-to-one)

    Use Phases as the central bridge. This lets both the fact table and the generated date list connect indirectly, avoiding many-to-many conflicts.

    To show ProjectTitle, you can either create a measure like:

    ProjectTitle :=
    CALCULATE (
        SELECTEDVALUE ( Projects[ProjectTitle] ),
        TREATAS ( VALUES ( DynamicDateSpan[PhaseId] ), FactTable[PhaseId] ),
        FactTable
    )
    

    Or build a calculated table if you need a flattened structure.

    This setup should meet your needs: dynamically showing each phase across all active dates, with project info, while maintaining a clean and performant model.

    hope this helps, please feel free to reach out for further issue.

     

    Thank you.