Desvincular con nombre de columna

127

Tengo una mesa StudentMarkscon columnas Name, Maths, Science, English. Los datos son como

Name,  Maths, Science, English  
Tilak, 90,    40,      60  
Raj,   30,    20,      10

Quiero arreglarlo de la siguiente manera:

Name,  Subject,  Marks
Tilak, Maths,    90
Tilak, Science,  40
Tilak, English,  60

Con Univot, puedo obtener Nombre, Marcas correctamente, pero no puedo obtener el nombre de la columna en la tabla de origen a la Subjectcolumna en el conjunto de resultados deseado.

¿Cómo puedo conseguir esto?

Hasta ahora he llegado a la siguiente consulta (para obtener Nombre, Marcas)

select Name, Marks from studentmarks
Unpivot
(
  Marks for details in (Maths, Science, English)

) as UnPvt
Tilak
fuente
1
¿Puedes publicar lo que has hecho hasta ahora? consulta / salida.
Hart CO

Respuestas:

204

Tu consulta está muy cerca. Debería poder utilizar lo siguiente, que incluye subjecten la lista de selección final:

select u.name, u.subject, u.marks
from student s
unpivot
(
  marks
  for subject in (Maths, Science, English)
) u;

Ver SQL Fiddle con demo

Taryn
fuente
@bluefeet ¿Hay alguna manera de que no necesite especificar los nombres (Matemáticas, Ciencias, Inglés)? Estoy haciendo esta operación en muchas tablas, todas con la misma estructura pero con diferentes nombres de columna.
LBogaardt
1
@LBogaardt No, debe definir explícitamente las columnas a incluir.
jjjjjjjjjjj
@LBogaardt Eche un vistazo a mi respuesta aquí , podría usar sql dinámico para desconectar sin especificar los nombres de columna.
Taryn
8

También puede probar el método estándar de desenvolvimiento de sql utilizando una secuencia de lógica con el siguiente código. El siguiente código tiene 3 pasos:

  1. cree múltiples copias para cada fila usando la unión cruzada (también creando columna de asunto en este caso)
  2. crear "marcas" de columna y completar los valores relevantes utilizando la expresión de mayúsculas y minúsculas (p. ej .: si el sujeto es ciencia, elija el valor de la columna de ciencia)
  3. eliminar cualquier combinación nula (si existe, la expresión de la tabla se puede evitar por completo si no hay valores nulos en la tabla base)

     select *
     from 
     (
        select name, subject,
        case subject
        when 'Maths' then maths
        when 'Science' then science
        when 'English' then english
        end as Marks
    from studentmarks
    Cross Join (values('Maths'),('Science'),('English')) AS Subjct(Subject)
    )as D
    where marks is not null;
Rahul Kohli
fuente
¡Esto también funciona con cualquier RDBMS! Los VALORES, cuando no están disponibles, pueden ser reemplazados por una subconsulta con SELECT ... UNION ... SELECT ... Sin embargo, me
Cristi S.
0

SELECCIONAR * DE estudiante

UNPIVOT (Marcas PARA asignaturas en (Matemáticas, Ciencias, Inglés));

Tutu Kumari
fuente
1
Esta ya es la misma respuesta que la respuesta aceptada y altamente votada publicada hace casi 6 años.
ImaginaryHuman072889
0

Otra forma de usar la unión cruzada sería especificar nombres de columna dentro de la unión cruzada

select name, Subject, Marks 
from studentmarks
Cross Join (
values (Maths,'Maths'),(Science,'Science'),(English,'English')
) un(Marks, Subject)
where marks is not null;
Jeyhun
fuente