3

How can I do the following please?

enter image description here

5
  • 1
    Which database system are you using? Commented Dec 1, 2012 at 20:11
  • Post the table structure that you are working with as well as what Yogendra asked. Commented Dec 1, 2012 at 20:12
  • How did you determine that you want C 10 18 0 9 and not (say) C 18 10 9 0? Commented Dec 1, 2012 at 20:15
  • I use Microsoft SQL Server Express. Commented Dec 1, 2012 at 20:21
  • Dear ruakh,no particular order. Commented Dec 1, 2012 at 20:23

1 Answer 1

4

You can use the PIVOT table operator to do transform the rows of these course's grades into column, like so:

SELECT  
  Course, 
  [1] AS "Grade 1", 
  [2] AS "Grade 2", 
  [3] AS "Grade 3", 
  [4] AS "Grade 4"
FROM
(
  SELECT 
    Course, 
    Grade, 
    ROW_NUMBER() OVER(PARTITION BY Course 
                      ORDER BY COURSE) rownum 
  FROM Grades
) t
PIVOT 
(
   MAX(Grade)
   FOR rownum IN([1], [2], [3], [4])
) p;

SQL Fiddle Demo

This will give you:

COURSE    GRADE 1   GRADE 2      GRADE 3     GRADE 4
  A         15        17          (null)     (null)
  B         12      (null)        (null)     (null)
  C         10        18            0           9

Note that: I used the ranking function ROW_NUMBER() with PARTITION BY Course to partition them into four grades. So that you could then group them into these four groups.

If you need to this dynamically, in case there was unknown number of grades. You can use dynamic SQL in this case to generate the list of grades dynamically like so:

DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);

SELECT @cols = STUFF((SELECT distinct ',' 
                        + QUOTENAME('Grade ' 
                        + CAST(ROW_NUMBER() OVER(PARTITION BY Course 
                                               ORDER BY Course) AS VARCHAR(10)))
                FROM Grades
                         FOR XML PATH(''), TYPE
                      ).value('.', 'NVARCHAR(MAX)'), 1, 1, '');

SELECT @query = 'SELECT Course, ' + @cols +  
                'FROM
                 (
                   SELECT 
                     Course, 
                     Grade, 
                     ''Grade '' + CAST(ROW_NUMBER() 
                                       OVER(PARTITION BY Course 
                                ORDER BY COURSE) AS VARCHAR(10)) rownum 
                   FROM Grades
                 ) t
                 PIVOT 
                 (
                   MAX(Grade)
                   FOR rownum IN(' + @cols + ')' +
                ') p';
execute(@query);

Dynamic SQL Fiddle Demo

Sign up to request clarification or add additional context in comments.

1 Comment

i would change row_number with dense_rank() so if there were double 15 marks it wont show in pivot like dense_rank() OVER(PARTITION BY Course ORDER BY grade)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.