microsoft / PowerBI-LogAnalytics-Template-Reports

The repository hosts Power BI template files that can be used to analyze Power BI data after you send it to Azure Log Analytics.
MIT License
110 stars 43 forks source link

Duplicate values on the one side of a one to many relationship #28

Open InsightfulAnalytics opened 3 months ago

InsightfulAnalytics commented 3 months ago

Hi Rui,

When refreshing the report created with the PBIASEngine, I get the error "Column query suboperation Key" in table Operation contains Duplicate values on the one side of a one to many relationship" as seen in the attached picture.

I then changed the relationship between the 2 tables operation and query sub operation to many to many and then I got another error for a different set of tables.

I then changed all of the relationships in the model to many to many and the refresh worked ok.

I am concerned that my reports may be impacted as many to many relationships are not desirable.

Do you know why the error is returned?

A screen shot of the model prior to change is also attached, it appears to match the er-diagram.

model

Thanks, Tim

InsightfulAnalytics commented 3 months ago

I'm getting there in resolving this, so far my results have found the source of the error in the KQL query:

for this function in PQ: fnGetOperationsExceptRefreshes


  let
      Source = OperationExceptRefresh_stage,
      MergeQueries = Table.NestedJoin(Source, {"XmlaRequestId"}, RefreshOperations, {"XmlaRequestId"}, "Suboperation", JoinKind.LeftAnti),
      AppendQuery = Table.Combine({MergeQueries, RefreshOperations}),

      //#"Renamed Columns" = Table.RenameColumns(AnalyticsQuery,{{"DurationMs", "Duration (ms)"}}),
      #"AddStartDateTime(UTCoffset)" = Table.AddColumn(AppendQuery, "Start DateTime", each[StartTime] + #duration(0,Number.RoundDown(#"UTC Offset Hours"),Number.RoundDown(60 * Number.Mod(#"UTC Offset Hours", 1)),0),type datetime),
      InsertedStartDate = Table.AddColumn(#"AddStartDateTime(UTCoffset)", "Start Date", each DateTime.Date([Start DateTime]), type date),
      InsertTime = Table.AddColumn(InsertedStartDate, "Start Time (s)", each DateTime.Time([Start DateTime]), type time),
      RemovOriginalStartTime = Table.RemoveColumns(InsertTime,{"StartTime"}),
      AddCustom = Table.AddColumn(RemovOriginalStartTime, "EndTime", each [Start DateTime] + #duration(0, 0, 0, [#"Duration (ms)"] / 1000)),

      ChangType1 = Table.TransformColumnTypes(AddCustom,{{"CpuTimeMs", Int64.Type}, {"Duration (ms)", Int64.Type}, {"EndTime", type datetimezone}, {"TextDataHash", Int64.Type}, {"Start DateTime", type datetimezone}, {"Start Date", type date}, {"Start Time (s)", type time}}),
      #"RenametoStartDate/Time" = Table.RenameColumns(ChangType1,{{"Start DateTime", "Start Date/Time"}}),
      RenameColumns = Table.RenameColumns(#"RenametoStartDate/Time",{{"CpuTimeMs", "CPUTime (ms)"}}),
      ChangeType2 = Table.TransformColumnTypes(RenameColumns,{{"TextDataHash", type text}}),
      RemoveDuplicates = Table.Distinct(ChangeType2),

      ChangeType3 = Table.TransformColumnTypes(RemoveDuplicates,{{"StatusCode", type number}}),
      RenameColumns1 = Table.RenameColumns(ChangeType3,{{"EndTime", "End Date/Time"}, {"WorkspaceName", "Workspace"}, {"OperationName", "Operation"}, {"OperationDetailName", "Operation Detail"}, {"Start Time (s)", "Start Time"}}),
      RemoveColumns = Table.RemoveColumns(RenameColumns1,{"Suboperation"}),
      AddIndex = Table.AddIndexColumn(RemoveColumns, "Index", 0, 1, Int64.Type),
      AddQuerySuboperationKey = Table.AddColumn(AddIndex, "Query Suboperation Key", each if [QuerySubeventKey] = "" or [QuerySubeventKey] = null then [Index] else [QuerySubeventKey]),
      AddRefreshSuboperationKey = Table.AddColumn(AddQuerySuboperationKey, "Refresh Suboperation Key", each if [RefreshSubeventKey] = null then [Index] else [RefreshSubeventKey]),
      AddAggSuboperationKey = Table.AddColumn(AddRefreshSuboperationKey, "Agg Suboperation Key", each if [QuerySubeventKey] = "" or [QuerySubeventKey] = null then [Index] else [QuerySubeventKey]),

      RemoveColumns1 = Table.RemoveColumns(AddAggSuboperationKey,{"QuerySubeventKey", "RefreshSubeventKey", "Index"}),
      RenameColumns2 = Table.RenameColumns(RemoveColumns1,{{"ExecutingUser", "Executing User"}})

  in
      RenameColumns2

// this is returning a duplicate value


    | extend QuerySubeventKey = case(
        OperationName == 'QueryEnd' and isnotempty(XmlaRequestId), XmlaRequestId,  // add rootActivityId as the key if this is a QueryEnd. This joins to the Suboperation table.
        dynamic(null)) // if we are not expecting subevents then make this null. In PowerQuery we will add a dummy index value for null values to keep this column unique for the 1:* relationship    

The XmlaRequestId is not a primary key, so for some reason the QueryEnd is appearing more than once on for the same XmlaRequestID.

I will continue my investigations

xiaozhangMS commented 3 months ago

Have you tried the https://github.com/microsoft/PowerBI-LogAnalytics-Template-Reports/blob/main/FabricASEngineAnalytics/FabricASEngineAnalytics.pbit?