Search code examples
sqloracle11gunpivot

SQL : oracle 11g, Split the result set into 2 subset and display side by side


I did unpivot that transformed columns to rows. http://sqlfiddle.com/#!4/fc489/6

now I would like to display to student information side by side something like

AVGGPA      1                    1
COURSEAVG   101.5                101.5
STUDENTNAME Jilly Doe            John Doe

Any hints??


Solution

  • If you really only have two subsets to worry about, a simple way to build on what you have so far is:

    SELECT labeln,
      MAX(CASE WHEN rn = 1 THEN value1 END) AS col1,
      MAX(CASE WHEN rn = 2 THEN value1 END) AS col2
    FROM (
      SELECT * FROM (
        SELECT to_char(avg(g1.grade)) AS avgGPa,
          to_char(avg(s1.course)) AS courseAVG,
          s1.student_name AS studentName,
          ROW_NUMBER() OVER (PARTITION BY NULL ORDER BY s1.student_name) AS RN
        FROM student s1
        JOIN grade g1 ON s1.student_name = g1.student_name
        GROUP BY s1.student_name
      )
      UNPIVOT (value1 FOR labeln IN (avggpa, courseavg, studentname))
    )
    GROUP BY labeln
    ORDER BY labeln;
    

    SQL Fiddle

    It's basically a manual pivot; adding a row_number() to your original query, and then using that to decide which column the corresponding values go in, with max() to collapse the blanks. You can easily add more columns by duplicating the max(case(...)) bit and just changing the rn check. But you have to know how many columns you need to end up with; or overestimate and have some blanks at the end.

    In theory you could use an actual pivot() but you don't know the values in advance, so you don't have values to use in the for clause. You could maybe use an XML approach, but that's maybe overkill; depending on what your real-world usage for this would be.