Desenvolver com o nome da coluna


127

Eu tenho uma mesa StudentMarkscom colunas Name, Maths, Science, English. Dados são como

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

Quero organizá-lo da seguinte maneira:

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

Com o univivido , sou capaz de obter Name, Marks corretamente, mas não consigo obter o nome da coluna na tabela de origem para a Subjectcoluna no conjunto de resultados desejado.

Como posso conseguir isso?

Até agora, cheguei à seguinte consulta (para obter Nome, Marcas)

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

) as UnPvt

1
Você pode postar o que você fez até agora? consulta / saída.
Hart CO

Respostas:


204

Sua consulta está muito próxima. Você deve poder usar o seguinte, que inclui o subjectna lista de seleção final:

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

Veja SQL Fiddle com demonstração


@bluefeet Existe uma maneira de você não precisar especificar os nomes (matemática, ciências, inglês)? Estou fazendo essa operação em muitas tabelas, todas com a mesma estrutura, mas com nomes de colunas diferentes.
LBogaardt

1
@LBogaardt Não, você precisa definir explicitamente as colunas a serem incluídas.
Jjjjjjjjjjj

@LBogaardt Dê uma olhada na minha resposta aqui , você pode usar o sql dinâmico para remover o dinamismo sem especificar os nomes das colunas.
Taryn

8

Você também pode tentar o método não-dinâmico de sql padrão usando uma sequência de lógica com o seguinte código. O código a seguir possui 3 etapas:

  1. crie várias cópias para cada linha usando junção cruzada (também criando coluna de assunto neste caso)
  2. crie "marcas" da coluna e preencha valores relevantes usando a expressão de caso (por exemplo: se o assunto é ciência, escolha valor na coluna ciência)
  3. remova qualquer combinação nula (se existir, a expressão da tabela poderá ser totalmente evitada se não houver valores nulos estritamente na tabela 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;

Isso também funciona com qualquer RDBMS! VALORES, quando não estiver disponível, pode ser substituído por uma subconsulta com SELECT ... UNION ... SELECT ... Quer saber sobre o desempenho dessa CROSS JOIN embora ...
Cristi S.

0

SELECT * FROM aluno

UNPIVOT (marcas para disciplinas em (matemática, ciências, inglês));


1
Essa já é a mesma resposta que a resposta aceita e altamente votada postada há quase 6 anos?
ImaginHuman072889

0

Outra maneira de usar a junção cruzada seria especificar nomes de colunas dentro da junção cruzada

select name, Subject, Marks 
from studentmarks
Cross Join (
values (Maths,'Maths'),(Science,'Science'),(English,'English')
) un(Marks, Subject)
where marks is not null;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.