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

Enhance your career with this limited time 50% discount on Fabric and Power BI exams. Ends August 31st. Request your voucher.

Reply
Suraj_Ncircle
Frequent Visitor

Efficient Way to Pivot Table with Duplicate Subjects per Student in Power Query

I have a dataset with columns: Student, Subject, and Score. I want to pivot it so that each subject becomes a separate column. The challenge is that a student can have the same subject multiple times (e.g., repeated assessments), and I want each occurrence to become a separate column (e.g., Math, Math_2, etc.), keeping each student on a single row.

I’ve achieved this using Table.Group, but it’s slow and inefficient with large datasets (30,000+ students, each with 10+ subjects). The current method involves checking for duplicate subjects per student, which is time-consuming.

Is there a more efficient way to perform this transformation in Power Query or M—perhaps by dynamically handling duplicates during the pivot step?

Any suggestions for improving performance would be greatly appreciated.


Example Dataset

StudentsSubjectScore
JohnMaths80
JohnMaths85
JohnEnglish78
AliceMaths90
AliceScience88
AliceMaths92
BobEnglish70
BobEnglish75
BobScience85


Desired result

StudentMathsMaths_2EnglishEnglish_2Science
John808578  
Alice9092  88
Bod  707585

 

 

let
    Source = Excel.Workbook(File.Contents("C:\Duplicate students.xlsx"), null, true),
    Sheet1_Sheet = Source{[Item="Sheet1",Kind="Sheet"]}[Data],
    #"Promoted Headers" = Table.PromoteHeaders(Sheet1_Sheet, [PromoteAllScalars=true]),
    AddIndex = Table.AddIndexColumn(#"Promoted Headers", "Index", 1, 1, Int64.Type),
    AddGroupedIndex = Table.Group(AddIndex, {"Student", "Subject"}, {
        {"AllRows", each Table.AddIndexColumn(_, "SubIndex", 1, 1, Int64.Type)}
    }),
    #"Removed Other Columns" = Table.SelectColumns(AddGroupedIndex,{"AllRows"}),
    ExpandRows = Table.Combine(#"Removed Other Columns"[AllRows]),
    #"Removed Columns" = Table.RemoveColumns(ExpandRows,{"Index"}),
    ReplaceValue = Table.ReplaceValue(#"Removed Columns", 1, "", Replacer.ReplaceValue, {"SubIndex"}),
    Custom1 = Table.AddColumn(ReplaceValue, "newSubject", each [Subject] & Text.From([SubIndex])),
    #"Removed Columns1" = Table.RemoveColumns(Custom1,{"Subject", "SubIndex"}),
    #"Pivoted Column" = Table.Pivot(#"Removed Columns1", List.Distinct(#"Removed Columns1"[newSubject]), "newSubject", "Score", List.Sum)
in
    #"Pivoted Column"

 




2 ACCEPTED SOLUTIONS
johnbasha33
Super User
Super User

@Suraj_Ncircle 

let
// Step 1: Load your base table
Source = Excel.Workbook(File.Contents("C:\Duplicate students.xlsx"), null, true),
Sheet1 = Source{[Item="Sheet1",Kind="Sheet"]}[Data],
Headers = Table.PromoteHeaders(Sheet1, [PromoteAllScalars=true]),

// Step 2: Add index per Student+Subject pair for uniqueness
AddIndexPerStudentSubject = Table.Group(
Headers, {"Student", "Subject"},
{{"Data", each Table.AddIndexColumn(_, "SubjectIndex", 1, 1), type table [Student=nullable text, Subject=nullable text, Score=nullable number, SubjectIndex=number]}}
),
Flattened = Table.Combine(AddIndexPerStudentSubject[Data]),

// Step 3: Create unique column name like "Maths", "Maths_2", etc.
AddSubjectIndexSuffix = Table.AddColumn(Flattened, "SubjectKey", each
if [SubjectIndex] = 1 then [Subject] else [Subject] & "_" & Text.From([SubjectIndex])
),

// Step 4: Remove unnecessary columns and prepare for pivot
Cleanup = Table.SelectColumns(AddSubjectIndexSuffix, {"Student", "SubjectKey", "Score"}),

// Step 5: Pivot
Pivoted = Table.Pivot(Cleanup, List.Distinct(Cleanup[SubjectKey]), "SubjectKey", "Score", List.Sum)
in
Pivoted

Did I answer your question? Mark my post as a solution! Appreciate your Kudos !!

View solution in original post

Omid_Motamedise
Super User
Super User

Hi @Suraj_Ncircle 

 

Just copy the following formula and paste it into the Advanced editor.

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45W8srPyFPSUfJNLMkoBtIWBkqxOpiipsiirnnpOZnFGUCWuQVY3DEnMzkVSbmlAYpwcHJmah6YZYFDvRFY2Ck/CdV0A+zCpkjCSGYDhWMB", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Students = _t, Subject = _t, Score = _t]),
    #"Grouped Rows" = Table.Group(Source, {"Students", "Subject"}, {{"Count", each Table.AddIndexColumn(_,"Index",1)}})[[Count]],
    #"Expanded Count" = Table.ExpandTableColumn(#"Grouped Rows", "Count", {"Students", "Subject", "Score", "Index"}, {"Students", "Subject", "Score", "Index"}),
    #"Merged Columns" = Table.CombineColumns(Table.TransformColumnTypes(#"Expanded Count", {{"Index", type text}}, "en-AU"),{"Subject", "Index"},Combiner.CombineTextByDelimiter(" ", QuoteStyle.None),"Merged"),
    #"Pivoted Column" = Table.Pivot(#"Merged Columns", List.Distinct(#"Merged Columns"[Merged]), "Merged", "Score", each try _{0} otherwise "")
in
    #"Pivoted Column"

 

If my answer helped solve your issue, please consider marking it as the accepted solution. It helps others in the community find answers faster—and keeps the community growing stronger!
You can also check out my YouTube channel for tutorials, tips, and real-world solutions in Power Query with the following link
https://youtube.com/@omidbi?si=96Bo-ZsSwOx0Z36h

View solution in original post

6 REPLIES 6
AlienSx
Super User
Super User

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    pivot = Table.Buffer(Table.Pivot(Source, List.Distinct(Source[Subject]), "Subject", "Score", (x) => x)),
    split = List.Accumulate(
        List.Skip(Table.ColumnNames(pivot)), 
        pivot, 
        (s, c) => Table.SplitColumn(s, c, (x) => x, List.Max(List.Transform(Table.Column(pivot, c), List.Count)))
    )
in
    split
v-hjannapu
Community Support
Community Support

Hi @Suraj_Ncircle,

I would also take a moment to thank @Omid_Motamedise  and @johnbasha33  for actively participating in the community forum and for the solutions you’ve been sharing in the community forum. Your contributions make a real difference.

I wanted to check if you had the opportunity to review the information provided. Please feel free to contact us if you have any further questions.

Regards,
Harshitha.

Hi @Suraj_Ncircle,
I hope the above details help you fix the issue. If you still have any questions or need more help, feel free to reach out. We’re always here to support you.

Regards,
Harshitha.

Hello @Suraj_Ncircle,
I wanted to follow up and see if you have had a chance to review the information that was shared. If you have any additional questions or need further clarification, please don’t hesitate to reach out. I am here to assist with any concerns you might have.

Regards,
Harshitha.

Omid_Motamedise
Super User
Super User

Hi @Suraj_Ncircle 

 

Just copy the following formula and paste it into the Advanced editor.

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45W8srPyFPSUfJNLMkoBtIWBkqxOpiipsiirnnpOZnFGUCWuQVY3DEnMzkVSbmlAYpwcHJmah6YZYFDvRFY2Ck/CdV0A+zCpkjCSGYDhWMB", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Students = _t, Subject = _t, Score = _t]),
    #"Grouped Rows" = Table.Group(Source, {"Students", "Subject"}, {{"Count", each Table.AddIndexColumn(_,"Index",1)}})[[Count]],
    #"Expanded Count" = Table.ExpandTableColumn(#"Grouped Rows", "Count", {"Students", "Subject", "Score", "Index"}, {"Students", "Subject", "Score", "Index"}),
    #"Merged Columns" = Table.CombineColumns(Table.TransformColumnTypes(#"Expanded Count", {{"Index", type text}}, "en-AU"),{"Subject", "Index"},Combiner.CombineTextByDelimiter(" ", QuoteStyle.None),"Merged"),
    #"Pivoted Column" = Table.Pivot(#"Merged Columns", List.Distinct(#"Merged Columns"[Merged]), "Merged", "Score", each try _{0} otherwise "")
in
    #"Pivoted Column"

 

If my answer helped solve your issue, please consider marking it as the accepted solution. It helps others in the community find answers faster—and keeps the community growing stronger!
You can also check out my YouTube channel for tutorials, tips, and real-world solutions in Power Query with the following link
https://youtube.com/@omidbi?si=96Bo-ZsSwOx0Z36h
johnbasha33
Super User
Super User

@Suraj_Ncircle 

let
// Step 1: Load your base table
Source = Excel.Workbook(File.Contents("C:\Duplicate students.xlsx"), null, true),
Sheet1 = Source{[Item="Sheet1",Kind="Sheet"]}[Data],
Headers = Table.PromoteHeaders(Sheet1, [PromoteAllScalars=true]),

// Step 2: Add index per Student+Subject pair for uniqueness
AddIndexPerStudentSubject = Table.Group(
Headers, {"Student", "Subject"},
{{"Data", each Table.AddIndexColumn(_, "SubjectIndex", 1, 1), type table [Student=nullable text, Subject=nullable text, Score=nullable number, SubjectIndex=number]}}
),
Flattened = Table.Combine(AddIndexPerStudentSubject[Data]),

// Step 3: Create unique column name like "Maths", "Maths_2", etc.
AddSubjectIndexSuffix = Table.AddColumn(Flattened, "SubjectKey", each
if [SubjectIndex] = 1 then [Subject] else [Subject] & "_" & Text.From([SubjectIndex])
),

// Step 4: Remove unnecessary columns and prepare for pivot
Cleanup = Table.SelectColumns(AddSubjectIndexSuffix, {"Student", "SubjectKey", "Score"}),

// Step 5: Pivot
Pivoted = Table.Pivot(Cleanup, List.Distinct(Cleanup[SubjectKey]), "SubjectKey", "Score", List.Sum)
in
Pivoted

Did I answer your question? Mark my post as a solution! Appreciate your Kudos !!

Helpful resources

Announcements
July 2025 community update carousel

Fabric Community Update - July 2025

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

July PBI25 Carousel

Power BI Monthly Update - July 2025

Check out the July 2025 Power BI update to learn about new features.

Top Kudoed Authors