Отменить сводку с именем столбца

127

У меня есть таблица StudentMarksсо столбцами Name, Maths, Science, English. Данные похожи на

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

Я хочу устроить это следующим образом:

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

С unpivot я могу правильно получить имя и метки, но не могу получить имя столбца в исходной таблице для Subjectстолбца в желаемом наборе результатов.

Как я могу этого добиться?

Я до сих пор дошел до следующего запроса (чтобы получить имя, отметки)

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

) as UnPvt
Тилак
источник
1
Можете ли вы опубликовать то, что вы уже сделали? запрос / вывод.
Hart CO

Ответы:

204

Ваш запрос очень близок. Вы должны иметь возможность использовать следующее, включая subjectв окончательный список выбора:

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

См. Демонстрацию SQL Fiddle

Тарин
источник
@bluefeet Есть ли способ, при котором вам не нужно указывать имена (математика, естественные науки, английский язык)? Я проделываю эту операцию со многими таблицами, все с одинаковой структурой, но с разными именами столбцов.
LBogaardt
1
@LBogaardt Нет, вам нужно явно указать столбцы, которые нужно включить.
jjjjjjjjjjj
@LBogaardt Взгляните на мой ответ здесь , вы можете использовать динамический sql для отмены поворота без указания имен столбцов.
Тарин
8

Вы также можете попробовать стандартный метод sql un-pivoting, используя последовательность логики со следующим кодом. Следующий код состоит из 3 шагов:

  1. создать несколько копий для каждой строки с помощью перекрестного соединения (в этом случае также создав столбец темы)
  2. создать столбец «метки» и заполнить соответствующие значения, используя выражение case (например: если предметом является наука, выберите значение из столбца «наука»)
  3. удалить любые нулевые комбинации (если существует, табличного выражения можно полностью избежать, если в базовой таблице строго нет нулевых значений)

     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;
Рахул Кохли
источник
Это также работает с любой СУБД! ЗНАЧЕНИЯ, когда они недоступны, могут быть заменены подзапросом с SELECT ... UNION ... SELECT ... Интересно, насколько эффективен CROSS JOIN ...
Кристи С.
0

ВЫБРАТЬ * ОТ студента

UNPIVOT (Оценки по предметам (математика, естественные науки, английский язык));

Туту Кумари
источник
1
Это уже тот же ответ, что и принятый и получивший высокую оценку ответ, опубликованный почти 6 лет назад?
ImaginaryHuman072889
0

Другой способ использования перекрестного соединения - указать имена столбцов внутри перекрестного соединения.

select name, Subject, Marks 
from studentmarks
Cross Join (
values (Maths,'Maths'),(Science,'Science'),(English,'English')
) un(Marks, Subject)
where marks is not null;
Джейхун
источник