0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Postgre SQL なんと外部キーでJOINできない状況に遭遇!!

Posted at

中規模な学習塾でデータ分析などをしています。塾で授業を受けている科目のテスト結果を抽出したい。ということが多々あります。
しかし、なんと、塾で授業を受けている科目のテスト結果を抽出する際に、外部キーでJOINできないという不思議な現象に出会いました。

テーブル

テーブルの中身はこんな感じになっています。
科目マスタ

 科目ID 科目名
1 英語
2 算数
3 国語
...
10 英語
11 数学
12 国語

授業テーブル

授業ID 生徒ID 生徒区分 講師ID 科目ID ...
1 123 中学生 987 1
2 456 中学生 654 1
3 789 中学生 321 1
4 135 中学生 975 2
5 791 中学生 864 2
6 246 中学生 310 2

テスト結果テーブル

テスト結果ID 生徒ID 科目ID 点数 ...
1 123 10 50
2 456 10 60
3 789 10 60
4 123 11 70
5 123 12 80
6 456 12 30

生徒が、何の授業を取っていて担当講師が誰なのかは「授業テーブル」にしかありません。
もちろんテスト結果は「テスト結果テーブル」にあります。
「テスト結果テーブル」と「授業テーブル」をJOINすれば、塾で授業を受けている科目のテスト結果を抽出できます。

問題発生

生徒IDと科目IDをKEYにしてJOINするんですが、「授業テーブル」の科目IDはつねに1桁のID、「テスト結果テーブル」の科目IDは常に2桁のIDになってます。
なぜかはわかりませんが、「授業テーブル」では中学生でも高校生でも小学生の科目IDが入るようになっています。「テスト結果テーブル」では中学生は中学生用の科目IDがふられています。
なぜこんな仕様になっているのか、作った人に小一時間問い詰めたい。(笑)
理由が分かる方は、ぜひ教えてください。

解決編

中学生は「国・数・理・社・英・音・体・美・技家」の9科目あります。どうも、「授業テーブル」の科目IDに+9をすると「テスト結果テーブル」の科目IDになるようです。
ということで、こんなSQLを書いてみました。

subject.sql
SELECT * FROM 授業テーブル 
INNER JOIN テスト結果テーブル 
    ON 授業テーブル.生徒ID = テスト結果テーブル.生徒ID 
    AND 授業テーブル.科目ID+9 = テスト結果テーブル.科目ID

これで、無事にテーブルをJOINできました。ON句の中で演算できるとは。
いやいや、きちんとシステム設計できていればこんな危ない解決策を取らなくてもいいのだけれど。
というか、普通はもっときちんとしたシステムだよね?

「もっと良い解決策あるよ。」という方、「間違いあるよ。」と指摘してくださる親切な方、ぜひコメントください。
よろしくお願いいたします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?