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

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
ericOnline
Post Patron
Post Patron

Generate Table of Contiguous Segments from Table of Individual Segments

Wow! This one is a baffler for me. Hoping some Power BI experts here can weigh in. 

Given:

- A composite unique key (first 4 columns of the sample data)

- A table of individual segments

Generate:

- A new table of contiguous segments based on the MIN(CUT_SEG_START) and MAX(CUT_SEG_END) for each unique key

Sample Data: See below

Desired Output: (Based on Sample Data below)

CUT_NUMBERCUT_SEGMENTCUT_SUBSEGMENTCUT_TYPECUT_SEG_STARTCUT_SEG_END
1570001M120.896131.985
1570002M120.896131.6

 

PowerBI Code tried so far: (not working)

 

CONTIGUOUS_TABLE = 
    SUMMARIZE(
        'SEGMENT_TABLE', 
        'SEGMENT_TABLE'[CUT_NUMBER], 
        'SEGMENT_TABLE'[CUT_SEGMENT], 
        'SEGMENT_TABLE'[CUT_SUBSEGMENT], 
        'SEGMENT_TABLE'[CUT_TYPE],
        "CUT_SEG_START", 
            IF(
                'SEGMENT_TABLE'[CUT_SEG_START] = EARLIER('SEGMENT_TABLE'[CUT_SEG_END])),
                MINX('SEGMENT_TABLE'[CUT_SEG_START]),
                'SEGMENT_TABLE'[CUT_SEG_START]
            ),
        "CUT_SEG_END", 
            IF(
                EARLIER('SEGMENT_TABLE'[CUT_SEG_END]) = 'SEGMENT_TABLE'[CUT_SEG_START],
                MAXX('SEGMENT_TABLE'[CUT_SEG_END]),
                'SEGMENT_TABLE'[CUT_SEG_START]
            )
    )

 

@Greg_Deckler  ever solved something like this with PBI?

Thank you!

---

Sample Data:

CUT_NUMBERCUT_SEGMENTCUT_SUBSEGMENTCUT_TYPECUT_SEG_STARTCUT_SEG_END

1570001M120.896128.342
1570001M128.342129.016
1570001M129.016129.191
1570001M129.191131.6
1570001M131.6131.806
1570001M131.806131.985
1570002M120.896128.344
1570002M128.344129.016
1570002M129.016129.192
1570002M129.192131.6
1 ACCEPTED SOLUTION

Hi @ericOnline ,

 

Please try the Power BI Store Version to open our pbix.

 

You can try M Query, not use the DAX.

 

1. Add an index column.

 

Ge1.jpg

 

2. Add another column that index column add 1.

 

Ge2.jpg

 

3. Merge the table based on two columns.

 

Ge3.jpg

 

4. Expand the Start column.

Then compare the new Start column and End column.

 

Ge4.jpg

 

5. Then add a column, if the Custom is False, then NULL.

 

Ge5.jpg

 

6. And we need to use the Fill up function.

 

Ge6.jpg

 

7. At last we use the GROUP BY function to get the result.

 

Ge7.jpg

 

If you have any question, please kindly ask here and we will try to resolve it.

 

Best regards,

 

Community Support Team _ zhenbw

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.


BTW, pbix as attached.

View solution in original post

9 REPLIES 9
mahoneypat
Employee
Employee

If you prefer or need to do it with DAX, here is the expression for the calculated table.

 

CONTIGUOUS_TABLE =
ADDCOLUMNS (
    SUMMARIZE (
        'SEGMENT_TABLE',
        'SEGMENT_TABLE'[CUT_NUMBER],
        'SEGMENT_TABLE'[CUT_SEGMENT],
        'SEGMENT_TABLE'[CUT_SUBSEGMENT],
        'SEGMENT_TABLE'[CUT_TYPE]
    ),
    "CUT_SEG_START", CALCULATE ( MIN ( Segment_Table[Cut_Seg_Start] ) ),
    "CUT_SEG_END", CALCULATE ( MAX ( Segment_Table[Cut_Seg_end] ) )
)

 

If this works for you, please mark it as the solution.  Kudos are appreciated too.  Please let me know if not.

Regards,

Pat





Did I answer your question? Mark my post as a solution! Kudos are also appreciated!

To learn more about Power BI, follow me on Twitter or subscribe on YouTube.


@mahoneypa HoosierBI on YouTube


Hi @mahoneypat ,

Thank you for the insights! Do you know how I would accommodate gaps between segments? Thats really the crux of the issue. 

Your suggested DAX results in a single record...

CUT_NUMBERCUT_SEGMENTCUT_SUBSEGMENTCUT_TYPECUT_SEG_STARTCUT_SEG_END
135470003M1154.25291.6

 

...where I'm looking for 3 records due to the gaps between the _END and _START of the segments...

CUT_NUMBERCUT_SEGMENTCUT_SUBSEGMENTCUT_TYPECUT_SEG_STARTCUT_SEG_END
135470003M1154.25171.513
135470003M2172.2235.632
135470003M3237.131291.6

 

Visualization:

image.png

 

Sample data for this example:

CUT_NUMBERCUT_SEGMENTCUT_SUBSEGMENTCUT_TYPECUT_SEG_STARTCUT_SEG_END
135473M1154.25155.039
135473M1155.039156.944
135473M1156.944157.053
135473M1157.053166
135473M1166171.4
135473M1171.4171.433
135473M1171.433171.513
135473M1172.2172.446
135473M1172.446175.5
135473M1175.5175.8
135473M1175.8180.109
135473M1180.109180.305
135473M1180.305181
135473M1181183.14
135473M1183.14183.229
135473M1183.229183.337
135473M1183.337184.2
135473M1184.2184.639
135473M1184.639184.9
135473M1184.9184.91
135473M1184.91185.079
135473M1185.079185.36
135473M1185.36185.381
135473M1185.381185.5
135473M1185.5186.125
135473M1186.125189.75
135473M1189.75197.669
135473M1197.669197.7
135473M1197.7197.9
135473M1197.9210.254
135473M1210.254210.479
135473M1210.479222.39
135473M1222.39222.396
135473M1222.396222.624
135473M1222.624235.517
135473M1235.517235.523
135473M1235.523235.63155
135473M1235.63155235.632
135473M1237.131237.238
135473M1237.238237.4
135473M1237.4239.788
135473M1239.788240
135473M1240241.9
135473M1241.9244.319
135473M1244.319244.555
135473M1244.555249.88
135473M1249.88254.514
135473M1254.514254.752
135473M1254.752269.901
135473M1269.901270.006
135473M1270.006270.155
135473M1270.155278.9
135473M1278.9279.125
135473M1279.125279.357
135473M1279.357291.397
135473M1291.397291.6

Hi @ericOnline ,

 

We need to create three columns to group the data, then we can create a table to meet your requirement.

 

1. Create three columns in SEGMENT_TABLE.

 

Column = 
[CUT_SEG_END]
    = CALCULATE (
        SUM ( 'SEGMENT_TABLE'[CUT_SEG_START]),
        'SEGMENT_TABLE',
        'SEGMENT_TABLE'[Index]
            = EARLIER ( 'SEGMENT_TABLE'[Index] ) + 1,
        'SEGMENT_TABLE'[CUT_NUMBER] = EARLIER ( 'SEGMENT_TABLE'[CUT_NUMBER] ),
        'SEGMENT_TABLE'[CUT_SEGMENT] = EARLIER ( 'SEGMENT_TABLE'[CUT_SEGMENT] ),
        'SEGMENT_TABLE'[CUT_SUBSEGMENT] = EARLIER ( 'SEGMENT_TABLE'[CUT_SUBSEGMENT] )
)

 

Group = 
VAR temp =
    CALCULATE (
        MAX ( 'SEGMENT_TABLE'[Index] ),
        'SEGMENT_TABLE',
        NOT ( 'SEGMENT_TABLE'[Column] ),
        'SEGMENT_TABLE',
        'SEGMENT_TABLE'[Index]
            < EARLIER ( 'SEGMENT_TABLE'[Index] ),
        'SEGMENT_TABLE'[CUT_NUMBER] = EARLIER ( 'SEGMENT_TABLE'[CUT_NUMBER] ),
        'SEGMENT_TABLE'[CUT_SEGMENT] = EARLIER ( 'SEGMENT_TABLE'[CUT_SEGMENT] ),
        'SEGMENT_TABLE'[CUT_SUBSEGMENT] = EARLIER ( 'SEGMENT_TABLE'[CUT_SUBSEGMENT] )
    )
RETURN
   IF (
        CALCULATE (
            COUNTROWS ( 'SEGMENT_TABLE' ),
            'SEGMENT_TABLE'[Column],
            'SEGMENT_TABLE',
            'SEGMENT_TABLE'[Index]
                = EARLIER ( 'SEGMENT_TABLE'[Index] ) - 1,
            'SEGMENT_TABLE'[CUT_NUMBER] = EARLIER ( 'SEGMENT_TABLE'[CUT_NUMBER] ),
            'SEGMENT_TABLE'[CUT_SEGMENT] = EARLIER ( 'SEGMENT_TABLE'[CUT_SEGMENT] ),
            'SEGMENT_TABLE'[CUT_SUBSEGMENT] = EARLIER ( 'SEGMENT_TABLE'[CUT_SUBSEGMENT] )
        ) > 0,
        CALCULATE (
            MIN ( 'SEGMENT_TABLE'[Index] ),
            'SEGMENT_TABLE',
            'SEGMENT_TABLE'[Index] < EARLIER ( 'SEGMENT_TABLE'[Index] ),
            'SEGMENT_TABLE'[Index] > temp,
            'SEGMENT_TABLE'[CUT_NUMBER] = EARLIER('SEGMENT_TABLE'[CUT_NUMBER]),
            'SEGMENT_TABLE'[CUT_SEGMENT] = EARLIER ( 'SEGMENT_TABLE'[CUT_SEGMENT] ),
            'SEGMENT_TABLE'[CUT_SUBSEGMENT] = EARLIER ( 'SEGMENT_TABLE'[CUT_SUBSEGMENT] )
        ),
        'SEGMENT_TABLE'[Index]
)

 

Rank = 
RANKX(
    FILTER('SEGMENT_TABLE','SEGMENT_TABLE'[CUT_NUMBER]=EARLIER('SEGMENT_TABLE'[CUT_NUMBER]) && 'SEGMENT_TABLE'[CUT_SEGMENT]=EARLIER('SEGMENT_TABLE'[CUT_SEGMENT]) && 'SEGMENT_TABLE'[CUT_SUBSEGMENT]='SEGMENT_TABLE'[CUT_SUBSEGMENT]),
    'SEGMENT_TABLE'[Group],,ASC,Dense)

 

G1.jpg

 

2. Then we can create a table using the following formula,

 

CONTIGUOUS_TABLE = 
ADDCOLUMNS (
    SUMMARIZE (
        'SEGMENT_TABLE',
        'SEGMENT_TABLE'[CUT_NUMBER],
        'SEGMENT_TABLE'[CUT_SEGMENT],
        'SEGMENT_TABLE'[CUT_SUBSEGMENT],
        'SEGMENT_TABLE'[Rank]
    ),
    "CUT_SEG_START", CALCULATE ( MIN ( 'SEGMENT_TABLE'[Cut_Seg_Start] ),FILTER('SEGMENT_TABLE','SEGMENT_TABLE'[Rank]=EARLIER('SEGMENT_TABLE'[Rank]))),
    "CUT_SEG_END", CALCULATE ( MAX ( 'SEGMENT_TABLE'[Cut_Seg_end] ),FILTER('SEGMENT_TABLE','SEGMENT_TABLE'[Rank]=EARLIER('SEGMENT_TABLE'[Rank] )))
)

 

G2.jpg

 

If it doesn’t meet your requirement, could you please show the exact expected result based on the table that you have shared?

 

Best regards,

 

Community Support Team _ zhenbw

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

 

BTW, pbix as attached.

Thank you for the insights @v-zhenbw-msft . I will test the code you provided now. 

I'm unable to open the attached .pbix for some reason.

It says "please install the latest version"...

image.png

...but I'm on the July 2020 PBI desktop version already...

ericOnline_0-1596476572843.png

No big deal 🙂 . I'll translate the code from your great post, just wanted you to be aware. 

 

Hello @v-zhenbw-msft ,

I was able to translate the code to my PBI file. I'm able to execute the code to create the "column" and "rank" columns, as well as the output table, but the code to create the "group" column will not execute.

Error:

ericOnline_0-1596486052759.png

I've increased the Data Cache to 8192MB and closed all programs except for PBI. Still will not execute. Any ideas for getting this query optimized to work on an 8GB RAM laptop?

Thank you

 

Hi @ericOnline ,

 

How about the result after you follow the suggestions mentioned in my original post?

If you've fixed the issue on your own please kindly share your solution.

If the above posts help, please kindly mark it as a solution to help others find it more quickly. Thanks!

 

Best regards,

 

Community Support Team _ zhenbw

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

Hi @v-zhenbw-msft ,

Thank you for the continued follow up. Sorry I'm late; I was unable to run the PowerQuery, again due to RAM(?). After a couple days, I tried again and was able to! Must have been background processes causing issue.

 

After running the steps you outlined, and troubleshooting a bit, I was able to get the desired results.

 

One caveat: In order for the method to work, I had to first sort the table by:

- CUT_NUM Ascending, then CUT_SEGMENT Ascending, then CUT_SUBSEGMENT Ascending

 

You're a great help @v-zhenbw-msft . Thank you for the expertise! Wow!

Hi @ericOnline ,

 

Please try the Power BI Store Version to open our pbix.

 

You can try M Query, not use the DAX.

 

1. Add an index column.

 

Ge1.jpg

 

2. Add another column that index column add 1.

 

Ge2.jpg

 

3. Merge the table based on two columns.

 

Ge3.jpg

 

4. Expand the Start column.

Then compare the new Start column and End column.

 

Ge4.jpg

 

5. Then add a column, if the Custom is False, then NULL.

 

Ge5.jpg

 

6. And we need to use the Fill up function.

 

Ge6.jpg

 

7. At last we use the GROUP BY function to get the result.

 

Ge7.jpg

 

If you have any question, please kindly ask here and we will try to resolve it.

 

Best regards,

 

Community Support Team _ zhenbw

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.


BTW, pbix as attached.

mahoneypat
Employee
Employee

This can be done with a Group By step, grouping on the first 4 columns, taking the Min of the 5th, and the Max of the 6th.  To see how it works, just create a blank query, go to Advanced Editor, and replace the text there with the M code below.

 

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("fZBLCsAwCETv4jqImk/1ED1Byf2v0SQuSglxEWbgPQLj8wBXSHAR0Qge754phGptNcVcBHo6mc5nMyRugencGxuH5uSjZcbgx0U9lWJvcm+mdTPlsLsEpvPzbjns3m8pv93y7e4v", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Cut_Number = _t, Cut_Segment = _t, Cut_Subsegment = _t, Cut_Type = _t, Cut_Seg_Start = _t, Cut_Seg_end = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Cut_Number", Int64.Type}, {"Cut_Segment", Int64.Type}, {"Cut_Subsegment", Int64.Type}, {"Cut_Type", type text}, {"Cut_Seg_Start", type number}, {"Cut_Seg_end", type number}}),
    #"Grouped Rows" = Table.Group(#"Changed Type", {"Cut_Number", "Cut_Segment", "Cut_Subsegment", "Cut_Type"}, {{"Cut_Seg_Start", each List.Min([Cut_Seg_Start]), type nullable number}, {"Cut_Seg_End", each List.Max([Cut_Seg_end]), type nullable number}})
in
    #"Grouped Rows"

 

If this works for you, please mark it as the solution.  Kudos are appreciated too.  Please let me know if not.

Regards,

Pat

 

 





Did I answer your question? Mark my post as a solution! Kudos are also appreciated!

To learn more about Power BI, follow me on Twitter or subscribe on YouTube.


@mahoneypa HoosierBI on YouTube


Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.