質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

1回答

739閲覧

OracleSQLのPIVOT関数を使って各科目(行)の成績分布(列)を表示し、かつそれらの数字の合計をカラムの一番右に追加したい。

Ryuichi_Yamamot

総合スコア11

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2017/10/20 06:45

編集2017/10/22 08:00

###前提・実現したいこと
以下の4つのテーブルがあります。

1
DEPARTMENT_TO_MAJOR: 大学の学部(または専攻)のコード(DCODE)と名前(DNAME)

2
Course:大学の講義のコードと講義名を持つ
科目コード、コース名

3
Section: 大学のセクション(section_id)のコードと所属している科目のコード(course_num)+その他
***ここではセクション=各学期に開かれる講義と定義します。例えば、「数学1」という科目(Course)が2017年春と2017年秋に開かれたとき、それぞれの学期の講義を別々のセクションとして認識します。セクションが多、科目が一の関係です)。

4
GRADE_REPORT: 学生番号(student_number)とその学生が履修したOR履修しているセクションのコード(section_id)とその成績(grade:履修中は空欄)を持つ。

以下のようなテーブルを作成したいです。
|学部名|科目コード|科目名|A|B|C|履修生徒数
|:--|:--:|--:|
|chemistry|001|organic chemistry|3|5|5|16|
|biology|002|genetics|2|1|0|10|
|physics|003|quantum physics|0|3|3|6|

科目をすべて列挙して、その科目を取った学生のGradeをGrade別にカウントして、さらにその合計を一番右に表示したいです。ただし、以下のような条件があります。
0. まだどの学生も、その科目のGradeを持ってない場合は、その科目は表示しません。
0. 一人の生徒は同じ科目を何度も受けられるとします(別セクションで)。その際、Gradeはそれぞれカウントします(e.g. CとBをとったらそれぞれ数えます)。
0. もし、Grade Dをとった生徒の数またはGrade Fをとった生徒の数がGrade Cをとった生徒の数より多かった場合は、その科目を表示しません。
0. Dept Name, A, B, C, D, F, Course Numberの順でソートします(A, B, C はDesc、それ以外はAcsです)。
###発生している問題・エラーメッセージ

自分でいろいろ試してみて、とりあえず、カラムだけは目的のテーブルと同じものができました。ただ、PIVOTがうまくいかず、Gradeの値とその合計がとれずすべて0になってしまいます。

今の私のコードの問題として以下があると思っているのですが、それをどうやって解決すればよいのかわかりません。。。
0. Inline selectの中のSQLではGradeのデータが取れているのに、Pivotではなぜかカウントされない。
0. 一番右のカラム"TotalEnroll"がPivotが分類する要素の一つになっていて合計をとるようになってない。

###試したこと
0. Pivot関数の中やその前のSelect句やInlineの別名をいろいろ変えてみる。
0. 下記のページを参考にいろいろ試してみる。でもうまくいきませんでした。
https://community.oracle.com/thread/1094307
https://www.insight-tec.com/mailmagazine/ora3/vol422.html

  1. 一番そとのSelect句で、具体的な列名を指定すると以下のエラーが出る(アスタリスクなら出ません)。

ORA-00904: "NumOfEnrollEachCo"."TotalEnrollEachCourse": invalid identifier
00904 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error at Line: 11 Column: 7

  1. Inline selectですでに取得したGradeの合計値を
    ,"NumOfStEachCo"."numOfStEachCo" as "TotalEnrollEachCourse"
    と書いて外のSQLでも使えるようにすると、そのカラムが”A”カラムの左に来てしまう。
  2. Inline selectですでに取得したGradeの合計値を
    ,"NumOfStEachCo"."numOfStEachCo" as "TotalEnroll"
    と書いて外のSQLでも使えるようにすると、以下のエラーが発生する。

ORA-00918: column ambiguously defined
00918 00000 - "column ambiguously defined"
*Cause:
*Action:
Error at Line: 4 Column: 5

###補足情報(言語/FW/ツール等のバージョンなど)
Oracle 12c を使ってOracle Developer上で動かしています。
ほかに何か必要な情報があれば、すぐに用意します。

どうか、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

「質問時に間違っていたPIVOTの使い方」
1PIVOTが呼ぶクエリのSelectでエイリアスをつけていた(つけているとエラーが出る)
2PIVOT関数内のfor の後ろには、PIVOTで分類されるデータを持ったカラムを設定する。
2PIVOT関数内のfor の前には、PIVOTで分類されるデータの集計方法を設定する。

例えば、以下のように書く。
pivot(count(GRADE) for GRADE in ('A' as A ,'B' as B,'C' as C)

「PIVOTで集計されたカラムの後ろに別のカラムを足す方法」
Pivotで作成したテーブルを丸々Inline selectにして、別のテーブルとJoinさせる。表示するカラムは、一番外側のSELECTで設定する。

例:
select
p.title
,p.A
,p.B
,p.c
,o.other_data
from (

PIVOTするためのテーブル(Inline select)

) PIVOTTABLE p join OTHERTABLE 0 on (p.pk = o.pk)

投稿2017/10/21 20:54

編集2017/10/23 07:48
Ryuichi_Yamamot

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問