2011-05-31 10 views
5

he reducido un esquema complejo para las siguientes muestraspivote complicado

estudiantes

  • int studentID, nombre varchar (50)
  • 1, Bill
  • 2, Amy
  • 3, Beth
  • 4, Scot t
  • 5, Steve

Clases

  • int ClassID, nombre varchar (50), VARCHAR Período (50)
  • 1, Algebra, PERIOD1
  • 2 , Geografía, Período3
  • 3, Biología, Período5
  • 4, Física, período4
  • 5, Discurso, Period2
  • 6, Historia, Period6

y una tabla de unión

StudentsClasses

  • studentID int , ClassID int
  • 1, 1
  • 1, 4
  • 1, 5
  • 2, 6
  • 3, 5
  • 3, 4
  • 3, 6
  • 4, 1
  • 4 , 4
  • 5, 5
  • 5, 6

Mi objetivo es hacer una lista de cada alumno con sus clases seleccionadas enumeradas en orden cronológico. Tengo el siguiente seleccione

SELECT Name,Period1, Period2, Period3, 
    Period4, Period5, Period6 
    FROM (
SELECT _Students.Name AS [NAME],_Classes.Period AS PIVOT_CODE, _Classes.name as [Class] 
FROM _Classes 
    INNER JOIN _StudentsClasses ON _Classes.ClassID=_StudentsClasses.ClassID 
    INNER JOIN _Students ON _StudentsClasses.StudentID=_Students.StudentID 
) 
    AS data 
    PIVOT 
    ( min([Class]) FOR [PIVOT_CODE] IN 
     (Period1, Period2, Period3, 
    Period4, Period5, Period6) 
    ) AS pvt 

que se traduce en

Name Period1 Period2 Period3 Period4 Period5 Period6 
------ --------- --------- --------- --------- --------- ---------- 
Amy NULL  NULL  NULL  NULL  NULL  History 
Beth NULL  Speech NULL  Physics NULL  History 
Bill Algebra Speech NULL  Physics NULL  NULL 
Scott Algebra NULL  NULL  Physics NULL  NULL 
Steve NULL  Speech NULL  NULL  NULL  History 

donde necesito ayuda es lo que necesito es para mover todos los no-nulos hacia la columna de la izquierda para que no haya espacios en blanco.Los nombres de columna se puede cambiar, por ejemplo

Name Choice1 Choice2 Choice3 Choice4 Choice5 Choice6 
------ --------- --------- --------- --------- --------- ---------- 
Amy History 
Beth Speech Physics History 
Bill Algebra Speech Physics 
Scott Algebra Physics 
Steve Speech History 

Puedo hacer esto mediante la selección del pivote en una tabla temporal entonces iterar sobre cada fila/columna con un cursor pero me gustaría evitar eso. Cualquier sugerencia es bienvenida.

+0

Qué DBMS está usando? –

Respuesta

5

Suponiendo SQL Server 2005 (por lo menos), utilizando ROW_NUMBER() para ordenar las opciones:

SELECT Name, Choice1, Choice2, Choice3, Choice4, Choice5, Choice6 
FROM (
    SELECT 
     S.Name AS [NAME], 
     'Choice' + CAST(ROW_NUMBER() OVER(PARTITION BY S.Name ORDER BY S.Name, C.Period) AS VARCHAR) AS PIVOT_CODE, 
     C.Name as [Class] 
    FROM Classes C 
     JOIN StudentsClasses SC ON C.ClassID = SC.ClassID 
     JOIN Students S ON SC.StudentID = S.StudentID 
    ) 
    AS data 
    PIVOT 
    ( min([Class]) FOR [PIVOT_CODE] IN 
     (Choice1, Choice2, Choice3, Choice4, Choice5, Choice6) 
    ) AS pvt 
+0

¡Agradable! No estaba al tanto de esta construcción, ¡gracias! – StuTheDog

+0

Me alegro de poder ayudar. – rsbarro