63
53

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 3 years have passed since last update.

SQL初心者〜中級者のための練習問題&解答例1

Last updated at Posted at 2020-11-21

SQL初心者〜中級者のための練習問題+解答例をいくつか作ってみました。
SQL力向上のためにお役立てください。

その2: SQL初心者〜中級者のための練習問題&解答例2
その3: SQL初心者〜中級者のための練習問題&解答例3

ツールの紹介

DB Fiddleを使うとブラウザ上で簡単にSQLを実行できます。
画面左側のSchema SQLにスキーマを、画面右側のQuery SQLにクエリ(SELECT句)を書いて、画面上部の「Run」ボタンを押すだけです。
環境構築要らないので便利です。

題材

学生テーブル

学籍番号 氏名 性別
0001 長岡 一馬
0002 中本 知佳
0003 松本 義文
0004 佐竹 友香

試験結果テーブル

学籍番号 教科 点数
0001 国語 30
0001 英語 30
0002 国語 70
0002 数学 80
0003 理科 92
0004 社会 90
0004 理科 35
0004 英語 22
Schema SQL
CREATE TABLE `students` (
  `id` int(4) unsigned zerofill NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `name` varchar(255) NOT NULL,
  `gender` varchar(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `students` (`id`, `name`, `gender`)
VALUES
    (0001, '長岡 一馬', '男'),
    (0002, '中本 知佳', '女'),
    (0003, '松本 義文', '男'),
    (0004, '佐竹 友香', '女');

CREATE TABLE `exam_results` (
  `student_id` int(4) unsigned zerofill NOT NULL,
  `subject` varchar(255) NOT NULL,
  `score` bigint(20) unsigned NOT NULL,
  PRIMARY KEY(`student_id`, `subject`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

INSERT INTO `exam_results` (`student_id`, `subject`, `score`)
VALUES
    (0001, '国語', 30),
    (0001, '英語', 30),
    (0002, '国語', 70),
    (0002, '数学', 80),
    (0003, '理科', 92),
    (0004, '社会', 90),
    (0004, '理科', 35),
    (0004, '英語', 22);

問1

性別が男である生徒の名前を一覧で表示せよ。

name
長岡 一馬
松本 義文
解答例
SELECT
	name
FROM
	students
WHERE
	gender = '男'

問2

1教科でも30点以下の点数を取った生徒の名前を一覧で表示せよ。
ただし、重複は許さないものとする。

name
長岡 一馬
佐竹 友香
解答例
SELECT DISTINCT
	s.name
FROM
	exam_results er
INNER JOIN students s
	ON er.student_id = s.id
WHERE
	er.score <= 30

問3

性別ごとに、最も高かった試験の点数を表示せよ。

gender max_score
92
90
解答例
SELECT
	s.gender,
	MAX(er.score) AS max_score
FROM
	students s
INNER JOIN exam_results er
	ON s.id = er.student_id
GROUP BY
	s.gender

問4

教科ごとの試験の平均点が50点以下である教科を表示せよ。

subject avg_score
国語 50.0000
英語 26.0000
解答例
SELECT
	subject,
    AVG(score) AS avg_score
FROM
	exam_results
GROUP BY
	subject
HAVING
	AVG(score) <= 50

問5

試験結果テーブルの点数の右に、その教科の平均点を表示せよ。

student_id subject score subject_avg_score
0001 国語 30 50.0000
0001 英語 30 26.0000
0002 国語 70 50.0000
0002 数学 80 80.0000
0003 理科 92 63.5000
0004 理科 35 63.5000
0004 社会 90 90.0000
0004 英語 22 26.0000
解答例1
SELECT
	er1.*,
	(
		SELECT
			AVG(er2.score)
		FROM
			exam_results er2
		WHERE
			er1.subject = er2.subject
	) AS subject_avg_score
FROM
	exam_results er1
解答例2(提供: @takahasinaoki さん)
SELECT
	*,
	AVG(score) OVER(PARTITION BY subject) AS subject_avg_score
FROM
	exam_results
ORDER BY 
	student_id

※MySQL8.0以上でしか動きません

問6

試験結果に理科が含まれない生徒の名前を一覧で表示せよ。

name
長岡 一馬
中本 知佳
解答例1
SELECT
	s.name
FROM
	students s
INNER JOIN exam_results er
	ON s.id = er.student_id
GROUP BY
	s.id
HAVING
	SUM(CASE WHEN er.subject = '理科'  THEN 1 ELSE 0 END) = 0
解答例2(提供: @takahasinaoki さん)
SELECT
	name
FROM
	students
WHERE 
	id NOT IN (
		SELECT
			student_id
		FROM
			exam_results
		WHERE
			subject = '理科'
	)
解答例3(提供: @takahasinaoki さん)
SELECT
	name
FROM
	students s
WHERE 
	NOT EXISTS (
		SELECT
			*
		FROM
			exam_results
		WHERE
			subject = '理科'
			AND
			student_id = s.id
	)
63
53
3

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
63
53

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?