MS SQL: Converting row printing to column based printing

Please support our MS SQL advertiser: Intel Parallel Studio Home
Thread Solved

Join Date: Dec 2008
Posts: 19
Reputation: dfs3000my is an unknown quantity at this point 
Solved Threads: 0
dfs3000my dfs3000my is offline Offline
Newbie Poster

MS SQL: Converting row printing to column based printing

 
0
  #1
Oct 29th, 2009
Hi, I am doing a student progression system where the application is able to keep track of student marks. I have a problem currently and I've been spending nights on this.

Let me briefly explain. Marks are calculated based on their hurdles. So for instance, H1 = xx%, H2 = xx%. The number of hurdles vary for different subjects. The code below is able to provide me the calculated marks based on each individual's hurdles in rows. However, I'm trying to output it in a horizontal format. Meaning:

Instead of:

xx%
xx%

I want it to be: xx% xx% (in two columns)

I've tried using the CASE clause in my SELECT section but that only works if the hurdles are static and fixed. My problem is the hurdles are dynamic as well. Is there anyone who has some idea on how to workaround this issue? Thanks in advance guys!!

  1. SELECT SUM(Marks.marks_value) * Hurdle.hurdle_weight / 100 AS total
  2. FROM Marks INNER JOIN
  3. Student ON Marks.student_id = Student.student_id INNER JOIN
  4. Class ON Student.student_id = Class.student_id INNER JOIN
  5. MarkingCriteria ON Marks.criteria_id = MarkingCriteria.criteria_id INNER JOIN
  6. AssessmentComponent ON MarkingCriteria.component_id = AssessmentComponent.component_id INNER JOIN
  7. Hurdle ON AssessmentComponent.hurdle_id = Hurdle.hurdle_id
  8. GROUP BY Hurdle.hurdle_id, Hurdle.hurdle_weight, Student.student_id, Class.student_id
  9. ORDER BY Hurdle.hurdle_id
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 3,258
Reputation: sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of 
Solved Threads: 581
Sponsor
sknake's Avatar
sknake sknake is offline Offline
.NET Enthusiast
 
0
  #2
Oct 29th, 2009
You shouldn't pivot a table (rows -> columns) dynamically. Lets say one person does 10k hurdles where the rest only have done 3... then everyone will have 9k columns of NULLs since they didn't have nearly enough data to pivot. You should probably tackle this issue at the application level and return your data as rows.
Scott Knake
Custom Software Development
Apex Software, Inc.
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 19
Reputation: dfs3000my is an unknown quantity at this point 
Solved Threads: 0
dfs3000my dfs3000my is offline Offline
Newbie Poster
 
0
  #3
Oct 29th, 2009
sknake: i am restricting the number of hurdles to 5 at the client level so i'm sure it wouldn't be much of a problem. if i am insisting on my design, how should i make it work? I can't use cross tabs as the hurdle_ids are dynamic.
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 3,258
Reputation: sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of 
Solved Threads: 581
Sponsor
sknake's Avatar
sknake sknake is offline Offline
.NET Enthusiast
 
1
  #4
Oct 29th, 2009
I posted an example of how to pivot a table in:
http://www.daniweb.com/forums/thread233907.html

I'm afraid your table setup is a little to complex to duplicate on the spot as I don't understand the relationships.

Here is the code from that thread:
  1. IF OBJECT_ID('tempdb..#Parts', 'U') IS NOT NULL DROP TABLE #Parts
  2. CREATE TABLE #Parts
  3. (
  4. ID int,
  5. ID2 int,
  6. PartNo varchar(10)
  7. )
  8. SET NOCOUNT ON
  9. INSERT INTO #Parts (ID, ID2, PartNo) Values (75, 23921, 'DENT')
  10. INSERT INTO #Parts (ID, ID2, PartNo) Values (75, 26145, 'PLGD')
  11. INSERT INTO #Parts (ID, ID2, PartNo) Values (75, 26145, 'PRRP')
  12. INSERT INTO #Parts (ID, ID2, PartNo) Values (75, 26145, 'SIST')
  13. INSERT INTO #Parts (ID, ID2, PartNo) Values (75, 57290, 'PRMD')
  14. INSERT INTO #Parts (ID, ID2, PartNo) Values (75, 57290, 'abc')
  15. INSERT INTO #Parts (ID, ID2, PartNo) Values (75, 57290, 'def')
  16. INSERT INTO #Parts (ID, ID2, PartNo) Values (75, 57290, 'ghi')
  17. INSERT INTO #Parts (ID, ID2, PartNo) Values (75, 57290, 'jkl')
  18. SET NOCOUNT OFF
  19.  
  20. SELECT ID, ID2,
  21. Max((Case When RowNumber = 1 Then PartNo Else '' End)) AS Part1,
  22. Max((Case When RowNumber = 2 Then PartNo Else '' End)) AS Part2,
  23. Max((Case When RowNumber = 3 Then PartNo Else '' End)) AS Part3,
  24. Max((Case When RowNumber = 4 Then PartNo Else '' End)) AS Part4
  25. FROM
  26. (
  27. SELECT ID, ID2, PartNo,
  28. ROW_NUMBER() OVER(PARTITION BY ID, ID2 ORDER BY PartNo ASC) AS RowNumber
  29. FROM #Parts
  30. ) AS tbl
  31. GROUP BY ID, ID2

Results:
  1. ID ID2 Part1 Part2 Part3 Part4
  2. ----------- ----------- ---------- ---------- ---------- ----------
  3. 75 23921 DENT
  4. 75 26145 PLGD PRRP SIST
  5. 75 57290 abc def ghi jkl
  6.  
  7. (3 row(s) affected)
Scott Knake
Custom Software Development
Apex Software, Inc.
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 19
Reputation: dfs3000my is an unknown quantity at this point 
Solved Threads: 0
dfs3000my dfs3000my is offline Offline
Newbie Poster
 
0
  #5
Oct 29th, 2009
hmm, let me get this right. First you are creating a temp table to store the data to replicate the problem. For my case, I do not need to create a temp table right?

Next, your insert statements are inserting to the temp table.

And finally, your selecting it out from those table?



  1. SELECT Student_1.student_id, SUM(Marks.marks_value) * Hurdle.hurdle_weight / 100 AS total
  2. FROM Marks INNER JOIN
  3. Student AS Student_1 ON Marks.student_id = Student_1.student_id INNER JOIN
  4. Class AS Class_1 ON Student_1.student_id = Class_1.student_id INNER JOIN
  5. MarkingCriteria ON Marks.criteria_id = MarkingCriteria.criteria_id INNER JOIN
  6. AssessmentComponent ON MarkingCriteria.component_id = AssessmentComponent.component_id INNER JOIN
  7. Hurdle ON AssessmentComponent.hurdle_id = Hurdle.hurdle_id
  8. GROUP BY Hurdle.hurdle_id, Hurdle.hurdle_weight, Student_1.student_id


And my output is this:

1 31.4
1 60
4 0.2
4 39.6


'total ' column is what I am trying to make pivot.
Last edited by dfs3000my; Oct 29th, 2009 at 5:46 am.
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 3,258
Reputation: sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of sknake has much to be proud of 
Solved Threads: 581
Sponsor
sknake's Avatar
sknake sknake is offline Offline
.NET Enthusiast
 
0
  #6
Oct 29th, 2009
The temp tables are just for simulating data so you could run the solution "as-is" to see how it works. You should only care about the selecting portion.
Scott Knake
Custom Software Development
Apex Software, Inc.
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 19
Reputation: dfs3000my is an unknown quantity at this point 
Solved Threads: 0
dfs3000my dfs3000my is offline Offline
Newbie Poster
 
0
  #7
Oct 29th, 2009
I have managed to get the output that I want and below is my code. It may look pretty messy but well, that's the way it is

Thanks sknake for your help!

  1. SELECT student_name, student_number, student_email,
  2. Max((CASE WHEN RowNumber = 1 THEN total ELSE '' END)) AS Hurdle1,
  3. Max((CASE WHEN RowNumber = 2 THEN total ELSE '' END)) AS Hurdle2,
  4. Max((CASE WHEN RowNumber = 3 THEN total ELSE '' END)) AS Hurdle3,
  5. Max((CASE WHEN RowNumber = 4 THEN total ELSE '' END)) AS Hurdle4,
  6. Max((CASE WHEN RowNumber = 5 THEN total ELSE '' END)) AS Hurdle5
  7.  
  8. FROM (SELECT Student.student_id, Student.student_name, Student.student_number, Student.student_email,
  9. ROW_NUMBER() OVER (PARTITION BY Student.student_id ORDER BY Student.student_id) AS RowNumber,
  10. SUM(Marks.marks_value) * Hurdle.hurdle_weight / 100 AS total
  11. FROM Marks INNER JOIN
  12. Student ON Marks.student_id = Student.student_id INNER JOIN
  13. Class ON Student.student_id = Class.student_id INNER JOIN
  14. MarkingCriteria ON Marks.criteria_id = MarkingCriteria.criteria_id INNER JOIN
  15. AssessmentComponent ON MarkingCriteria.component_id = AssessmentComponent.component_id INNER JOIN
  16. Hurdle ON AssessmentComponent.hurdle_id = Hurdle.hurdle_id
  17. GROUP BY Hurdle.hurdle_id, Hurdle.hurdle_weight, Student.student_id, Student.student_name, Student.student_number,
  18. Student.student_email) AS derive
  19.  
  20. GROUP BY student_id, student_name, student_number, student_email

Output:
StudentName StudentNumber StudentEmail Hurdle1 Hurdle2 Hurdle3 Hurdle4 Hurdle5
Adam 0120R22222 adam@hotmail.com 31.5 60 0 0 0
James 4120R22222 james@hotmail.com 0.2 39.6 0 0 0
Last edited by dfs3000my; Oct 29th, 2009 at 6:20 am.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC