Non ruotare con il nome della colonna


127

Ho una tabella StudentMarkscon colonne Name, Maths, Science, English. I dati sono come

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

Voglio farlo organizzato come segue:

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

Con unpivot sono in grado di ottenere Nome, Marks correttamente, ma non riesco a ottenere il nome della colonna nella tabella di origine nella Subjectcolonna nel set di risultati desiderato.

Come posso raggiungere questo obiettivo?

Finora ho raggiunto la seguente query (per ottenere nome, segni)

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

) as UnPvt

1
Puoi pubblicare quello che hai fatto finora? interrogazione / uscita.
Hart CO,

Risposte:


204

La tua richiesta è molto vicina. Dovresti essere in grado di utilizzare quanto segue che include subjectnell'elenco di selezione finale:

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

Vedi SQL Fiddle con demo


@bluefeet Esiste un modo in cui non è necessario specificare i nomi (matematica, scienze, inglese)? Sto eseguendo questa operazione su molte tabelle, tutte con la stessa struttura ma con nomi di colonna diversi.
LBogaardt,

1
@LBogaardt No, devi definire esplicitamente le colonne da includere.
jjjjjjjjjjj,

@LBogaardt Dai un'occhiata alla mia risposta qui , potresti usare sql dinamico per annullare la rotazione senza specificare i nomi delle colonne.
Taryn

8

È inoltre possibile provare il metodo sql non-pivoting utilizzando una sequenza di logica con il seguente codice. Il codice seguente prevede 3 passaggi:

  1. creare più copie per ogni riga usando il cross join (anche creando la colonna dell'oggetto in questo caso)
  2. crea una colonna "mark" e inserisci i valori pertinenti usando l'espressione case (es: se la materia è scienza, scegli il valore dalla colonna science)
  3. rimuove qualsiasi combinazione nulla (se esiste, l'espressione della tabella può essere completamente evitata se non ci sono valori null nella tabella 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;

Questo funziona anche con qualsiasi RDBMS! I VALORI, quando non disponibili, possono essere sostituiti da una sottoquery con SELEZIONA ... UNIONE ... SELEZIONA ... Chiedendosi le prestazioni di quel CROSS JOIN però ...
Cristi S.

0

SELEZIONA * DA studente

UNPIVOT (Contrassegni per le materie in (matematica, scienze, inglese));


1
Questa è già la stessa risposta della risposta accettata e altamente votata pubblicata quasi 6 anni fa?
ImaginaryHuman072889

0

Un altro modo per aggirare il cross join sarebbe quello di specificare i nomi delle colonne all'interno del cross join

select name, Subject, Marks 
from studentmarks
Cross Join (
values (Maths,'Maths'),(Science,'Science'),(English,'English')
) un(Marks, Subject)
where marks is not null;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.