MySQLを使って以下の手順で作業を進めよ。
●sales_appデータベースを文字コードUTF-8で作成する。
CREATE DATABASE sales_app |
DEFAULT CHARACTER SET utf8; |
●sales_appにdepsテーブルを作成する。カラム構成は以下
id 整数 主キー 自動連番
dep 可変長文字列(30) NOT NULL
id INT PRIMARY KEY AUTO_INCREMENT, |
●depsテーブルに以下の情報を追加する(コピペしてよい)
INSERT INTO deps(dep) VALUES |
('営業1課'),('営業2課'),('経理部'),('総務部'),('人事部'); |
●sales_appにempsテーブルを作成する。カラム構成は以下
id 整数 主キー 自動連番
name 可変長文字列(30) NOT NULL,
age 整数
dep_id 整数
id INT PRIMARY KEY AUTO_INCREMENT, |
name VARCHAR(30) NOT NULL, |
●empsテーブルに以下のデータを挿入する。(コピペしてよい)
INSERT INTO emps(name,age,dep_id) VALUES |
●sales_appにsalesテーブルを作成する。カラム構成は以下
id 整数 主キー 自動連番
emp_id INT,
sale INT,
s_date DATE
id INT PRIMARY KEY AUTO_INCREMENT, |
●salesテーブルに以下のデータを挿入する。(コピペしてよい)
INSERT INTO sales(emp_id,sale,s_date) VALUES |
上記で作成したテーブルにおいて以下の処理を実現するSQL文を記せ。
1.empsテーブルに、山田,22,1を追加せよ。
2.depsの全てのデータを抽出せよ。
3.empsテーブルidが5のデータの年齢を1加えよ。
4.salesテーブルidが16のデータを削除せよ。
5.salesテーブル。sale降順に抽出せよ。
6.empsのデータを年齢降順に抽出せよ。取得項目は、名前、年齢とする。
7.empsテーブル。年齢が30以上でdep_idが4でないデータを抽出。
8.empsテーブル。名前に[中]が含まれない人を抽出せよ。
9.salesテーブル。2017-09-01~2017-09-03のデータを抽出する。
10.salesとempsを内部結合。売上を記録した人の名前を抽出。重複は除外すること。
11.depsテーブル。idの1,2は本社ビル7F,3,4は本社ビル6F,その他は本社ビル5Fである。
以下の項目名で取得せよ。部署名、所在地
12.empsテーブル。全件抽出。ただし年齢が23歳以下の人には名前の前に(新)を付与すること。
取得項目は名前、年齢
13.salesテーブル。sale昇順に並び替え。saleに1000を掛け3桁毎にカンマを挿入し末尾に円を付与したものを売上高とする。
取得項目は日付、売上高
14.salesテーブル。売上の合計、最大、最小、平均、データ数を表示する。
15.salesテーブル。2017-09-03の日別売上を求めよ。項目名は日付、件数、日別売上とする。
16.depsとempsを内部結合し年齢昇順に抽出せよ。ただし年齢は30歳未満。取得項目は、名前、年齢、部署名とする。年齢が同じ場合は部署名を辞書順に並べること。

17.salesとempsとdepsを内部結合し、取得項目名を日付,名前,年齢,部署名,売上高として全件抽出せよ。
18.salesとempsとdepsを左結合し、総売上個人ランキングトップ3を降順で取得する。取得項目は名前、部署名、総売上とする。
19.まだ売上を上げていない社員名を抽出せよ。
—-解答例—-
1.
INSERT INTO emps(name,age,dep_id) |
2.
3.
UPDATE emps SET age=age+1 |
4.
DELETE FROM sales WHERE id=16; |
5.
6.
SELECT name AS 名前,age AS 年齢 FROM emps |
7.
8.
WHERE name NOT LIKE '%中%'; |
9.
WHERE s_date BETWEEN '2017-09-01' AND '2017-09-03'; |
10.
11.
CASE WHEN id IN(1,2) THEN '本社ビル7F' |
WHEN id IN(3,4) THEN '本社ビル6F' |
12.
CASE WHEN age<=23 THEN concat('(新)',name) |
13.
SELECT s_date AS 日付,concat(format(sale*1000,0),'円') AS 売上高 |
14.
SELECT sum(sale),max(sale),min(sale),avg(sale),count(*) |
15.
HAVING s_date='2017-09-03' |
(whereで絞り込んでからGROPU BY でもOK)
SELECT s_date AS 日付, count(*) AS 件数, sum(sale) AS 日別売上 FROM sales |
WHERE s_date='2017-09-03' GROPU BY s_date |
(1日だったらwhereだけでもOK)
SELECT s_date AS 日付, count(*) AS 件数, sum(sale) AS 日別売上 FROM sales |
WHERE s_date='2017-09-03' |
16.
SELECT e.name AS 名前,e.age AS 年齢,d.dep AS 部署名 |
ORDER BY e.age ASC,d.dep ASC; |
17.
18.
19.
WHERE id NOT IN(SELECT emp_id FROM sales); |
★★More★★
ここからは受講生の作成したお題からのピックアップです!
●部署毎に売上合計の高い人から並べて表示。取得項目は部署名,名前,売上合計。並び順は部署名昇順、売上降順とする。(W氏)

★GROUP BY に複数カラム指定することができる。
●2017年9月の個人売上高ランキングTOP5を取得せよ。取得項目は名前,売上。並びは売上降順とする。(F氏)

WHERE s.s_date BETWEEN '2017-09-01' AND '2017-09-30' |
●20代、30代、40代の売上合計を取得せよ。取得項目は年代、売上。並びは年代昇順とする。

WHEN e.age BETWEEN 20 AND 29 THEN '20-29' |
WHEN e.age BETWEEN 30 AND 39 THEN '30-39' |
WHEN e.age BETWEEN 40 AND 49 THEN '40-49' |
●まだ売り上げを上げていない社員を抽出し、一番年齢の高い社員のデータを削除せよ(K氏)
★この問題は1部難しい内容を含んでいるのでまずはSELECTしてみる
WHERE id NOT IN (SELECT emp_id FROM sales) |

どうやら田中さんが対象者のようだ。ではSELECTをDELETEにして田中さんを首にしよう。
WHERE id NOT IN (SELECT emp_id FROM sales) |
がしかし。。。

1093エラーが出てしまう。このようにUPDATEやDELETEはサブクエリに同じテーブルを直接含むことができない。
ハック的なのだがこの場合以下のように対応する
WHERE id NOT IN (SELECT emp_id FROM sales) |
直接empsテーブルをサブクエリで対象にしてしまうとエラーになるのでこの部分をもう一段回サブクエリを作ってあげて別名をつけてあげるとうまくいく。1093エラーはたまに遭遇するので覚えておくと良いだろう。
コメント