Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pivot rows into columns (custom pivoting)

Tags:

sql

tsql

pivot

I have a Sql Database table similar to the following:

Day   Period    Subject  Mon   1         Ch Mon   2         Ph Mon   3         Mth Mon   4         CS Mon   5         Lab1 Mon   6         Lab2 Mon   7         Lab3 Tue   1         Ph Tue   2         Ele Tue   3         Hu Tue   4         Ph Tue   5         En Tue   6         CS2 Tue   7         Mth 

I would like it displayed as follows: Kind of crosstab or Pivot

Day   P1   P2   P3   P4   P5   P6   P7  Mon   Ch   Ph   Mth  CS2  Lab1 Lab2 Lab3 Tue   Ph   Ele  Hu   Ph   En   CS2  Mth 

What would be the ideal way to do it? Can someone please show me the Sql code please?

like image 965
Babu Avatar asked Jun 25 '10 19:06

Babu


People also ask

Can pivot tables be customized?

Pick the style you want to use. If you don't see a style you like, you can create your own. Click New PivotTable Style at the bottom of the gallery, provide a name for your custom style, and then pick the options you want.

How do I switch rows and columns in a pivot table?

So how do you do it? Right click the PivotChart and choose Select Data. The Switch Row/Column button is hiding in there. Click OK once you have clicked it.

How do I create a custom column in a pivot table?

Click on the PivotTable, go to the tab PivotTable Tools at the top > Options > Fields, Items & Sets > Calculated Field. From there you could add fields which will then be added to the grand total. The downside is that you will have twice the number of columns for one additional field, thrice for 2 additional, etc.


2 Answers

You could probably do it with the PIVOT function, but I prefer the old school method:

SELECT     dy,     MAX(CASE WHEN period = 1 THEN subj ELSE NULL END) AS P1,     MAX(CASE WHEN period = 2 THEN subj ELSE NULL END) AS P2,     MAX(CASE WHEN period = 3 THEN subj ELSE NULL END) AS P3,     MAX(CASE WHEN period = 4 THEN subj ELSE NULL END) AS P4,     MAX(CASE WHEN period = 5 THEN subj ELSE NULL END) AS P5,     MAX(CASE WHEN period = 6 THEN subj ELSE NULL END) AS P6,     MAX(CASE WHEN period = 7 THEN subj ELSE NULL END) AS P7 FROM     Classes GROUP BY     dy ORDER BY     CASE dy         WHEN 'Mon' THEN 1         WHEN 'Tue' THEN 2         WHEN 'Wed' THEN 3         WHEN 'Thu' THEN 4         WHEN 'Fri' THEN 5         WHEN 'Sat' THEN 6         WHEN 'Sun' THEN 7         ELSE 8     END 
  • I changed some column names to avoid reserved words
like image 195
Tom H Avatar answered Sep 25 '22 08:09

Tom H


Just incase you do want the new school method. (The Pivot statement should work in SQL2005+, the VALUES bit for the example data only SQL2008)

WITH ExampleData AS ( SELECT X.*   FROM (VALUES   ('Mon', 1, 'Ch'), ('Mon', 2, 'Ph'), ('Mon', 3, 'Mth'), ('Mon', 4, 'CS'), ('Mon', 5, 'Lab1'), ('Mon', 6, 'Lab2'), ('Mon', 7, 'Lab3'), ('Tue', 1, 'Ph'), ('Tue', 2, 'Ele'), ('Tue', 3, 'Hu'), ('Tue', 4, 'Ph'), ('Tue', 5, 'En'), ('Tue', 6, 'CS2'), ('Tue', 7, 'Mth') ) AS X (Day,   Period,    Subject) )  SELECT Day, [1] AS P1, [2] AS P2,[3] AS P3, [4] AS P4, [5] AS P5,[6] AS P6,[7] AS P7 FROM ExampleData PIVOT   (   Max(Subject)   FOR Period IN ([1], [2],[3],[4], [5],[6], [7])   ) AS PivotTable;  

Result

Day  P1   P2   P3   P4   P5   P6   P7 ---- ---- ---- ---- ---- ---- ---- ---- Mon  Ch   Ph   Mth  CS   Lab1 Lab2 Lab3 Tue  Ph   Ele  Hu   Ph   En   CS2  Mth 
like image 29
Martin Smith Avatar answered Sep 25 '22 08:09

Martin Smith