列名を使用してアンピボット


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

アンピボット私はきちんと名前、マークを取得することができていますが、これにソース表の列名を取得することができません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 2017

1
@LBogaardtいいえ、含める列を明示的に定義する必要があります。
jjjjjjjjjjj 2017

@LBogaardt ここで私の答えを見てください。動的SQLを使用して、列名を指定せずにアンピボットできます。
タリン

8

次のコードで一連のロジックを使用して、標準のSQLアンピボットメソッドを試すこともできます。次のコードには3つのステップがあります。

  1. クロス結合を使用して各行に複数のコピーを作成します(この場合もサブジェクト列を作成します)
  2. 列「マーク」を作成し、ケース式を使用して関連する値を入力します(例:主題が科学の場合、科学の列から値を選択)
  3. nullの組み合わせを削除します(存在する場合、ベーステーブルにnull値が厳密に存在しない場合、テーブル式は完全に回避できます)。

     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;

これはどのRDBMSでも機能します!VALUESが利用できない場合は、SELECT ... UNION ... SELECT ...を使用してサブクエリに置き換えることができます

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;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.