AP データベース SQL基礎2
AP データベースへ戻る。
AP データベース SQL基礎へ戻る。
社員ID | 氏名 | 所属部署 | 給与 |
---|---|---|---|
1 | 山田太郎 | 営業部 | 300000 |
2 | 佐藤花子 | 開発部 | 400000 |
3 | 鈴木一郎 | 営業部 | 350000 |
4 | 田中美咲 | 総務部 | 280000 |
ALTER TABLE
表に対する様々な変更をする句です。ALTER TABLEに続けて使うキーワードで、
- 1.列の追加 (ADD COLUMN):
- 既存のテーブルに新しい列を追加します。
- 2.列の削除 (DROP COLUMN):
- 既存のテーブルから列を削除します。
- 3.列の変更 (ALTER COLUMN / MODIFY COLUMN):
- 既存の列のデータ型、NULL許容性、デフォルト値などを変更します。構文はデータベースシステムによって異なる場合があります(例: SQL Server, PostgreSQLはALTER COLUMN、MySQLはMODIFY COLUMN)。
- 4.列名の変更 (RENAME COLUMN):
- 既存の列の名前を変更します。これもデータベースシステムによって構文が異なります (例: RENAME COLUMN old_name TO new_nameやCHANGE old_name new_name data_type)。
- 5.制約の追加・削除 (ADD CONSTRAINT / DROP CONSTRAINT):
- 主キー、外部キー、UNIQUE、CHECKなどの制約を追加または削除します。
- 6.テーブル名の変更 (RENAME TO):
- テーブル自身の名前を変更します。
- 1.列の追加
ALTER TABLE 社員
ADD COLUMN 入社日 DATE;
sql
社員ID | 氏名 | 所属部署 | 給与 | 入社日 |
---|---|---|---|---|
1 | 山田太郎 | 営業部 | 300000 | NULL |
2 | 佐藤花子 | 開発部 | 400000 | NULL |
3 | 鈴木一郎 | 営業部 | 350000 | NULL |
4 | 田中美咲 | 総務部 | 280000 | NULL |
このように列が追加されます。次は列を削除してもとに戻します。
2.列の変更
ALTER TABLE 社員
MODIFY COLUMN 給与 BIGINT NOT NULL;
sql
上記で、社員テーブルの給与列にBIGINT型を設定して、NOT NULL制約を指定できます。
- 3.列の削除
ALTER TABLE 社員
DROP COLUMN 入社日;
sql
社員ID | 氏名 | 所属部署 | 給与 |
---|---|---|---|
1 | 山田太郎 | 営業部 | 300000 |
2 | 佐藤花子 | 開発部 | 400000 |
3 | 鈴木一郎 | 営業部 | 350000 |
4 | 田中美咲 | 総務部 | 280000 |
4.制約の追加
ALTER TABLE 社員
ADD CONSTRAINT PK_社員ID PRIMARY KEY (社員ID);
sql
上記のようにすると社員テーブルの社員ID列を主キー設定にし、一意な値を保持し、NOT NULL制約を適用できます。
外部キー制約の追加
外部キー制約を追加する場合は以下のようになります。
ALTER TABLE 社員
ADD CONSTRAINT FK_社員_部署
FOREIGN KEY (所属部署)
REFERENCES 部署テーブル (部署名);
sql
外部キーを設定する列をFOREIGN KEY (所属部署)のように列指定し、外部キーとして参照するテーブルと列を、REFERENCES 部署テーブル (部署名)で指定するという記述方法になります。
5.制約の削除
ALTER TABLE 社員
DROP CONSTRAINT PK_社員ID;
sql
上記のようにすると社員テーブルの社員IDの制約を削除することができます。
6.テーブル名の変更
ALTER TABLE 社員
RENAME TO 従業員;
sql
上記のようにすると社員テーブルを従業員テーブルという名前に変更できます。
ON DELETE CASCADE・ON UPDATE CASCADE
外部キーの削除変更があれば連動して、更新されたり、削除されたりする仕組みを形成します。
ALTER TABLE 社員
ADD CONSTRAINT FK_社員_部署 FOREIGN KEY (所属部署)
REFERENCES 部署テーブル (部署名)
ON DELETE CASCADE
ON UPDATE CASCADE;
sql
このように連動定義をしていると
DELETE FROM 部署テーブル
WHERE 部署名 = '総務部';
sql
のようにして総務部を削除すると、部署テーブルは
部署名 | 拠点 |
---|---|
営業部 | 東京 |
開発部 | 大阪 |
試作部 | 三重 |
となり
社員ID | 氏名 | 所属部署 | 給与 |
---|---|---|---|
1 | 山田太郎 | 営業部 | 300000 |
2 | 佐藤花子 | 開発部 | 400000 |
3 | 鈴木一郎 | 営業部 | 350000 |
社員テーブルはこのように自動的に総務部の情報がなくなります。
また営業部の名称を営業部から営業戦略部のように変更する以下のSQLを実行すると
UPDATE 部署テーブル
SET 部署名 = '営業戦略部'
WHERE 部署名 = '営業部';
sql
部署テーブルは以下のようになり
部署名 | 拠点 |
---|---|
営業戦略部 | 東京 |
開発部 | 大阪 |
試作部 | 三重 |
となり、社員テーブルは
社員ID | 氏名 | 所属部署 | 給与 |
---|---|---|---|
1 | 山田太郎 | 営業戦略部 | 300000 |
2 | 佐藤花子 | 開発部 | 400000 |
3 | 鈴木一郎 | 営業戦略部 | 350000 |
のように連動して値が変更されます。便利ですが、本当に置き換えてしまうことで解決する関係であるかどうかまで熟知して利用する必要があります。
CREATE USER
SQLシステムにログインして表を扱うユーザを追加する操作です。
CREATE USER report_user WITH PASSWORD 'password123';
CREATE USER app_user WITH PASSWORD 'password456';
sql
これでレポートを出力するためのユーザreport_user(任意のユーザ名)とアプリを動かすときにアプリがSQL問合せをするときの権限のユーザapp_userをそれぞれパスワードを指定して作成したことになります。
REVOKE
権限をなくすための句です。
REVOKE ALL PRIVILEGES ON TABLE 社員 FROM report_user;
REVOKE ALL PRIVILEGES ON TABLE 部署テーブル FROM report_user;
REVOKE ALL PRIVILEGES ON TABLE 社員 FROM app_user;
REVOKE ALL PRIVILEGES ON TABLE 部署テーブル FROM app_user;
sql
すべての権限を各テーブルからはく奪するには上記のようなSQLを使います。
GRANT
ユーザの権限と表の権限の関係を設定するものです。
GRANT SELECT ON TABLE 社員 TO report_user;
GRANT SELECT ON TABLE 部署テーブル TO report_user;
sql
部署テーブルと社員テーブルにselectのような射影操作だけをreport_userに許可する権限設定となりました。
これでreport_userは以下のようなSQLが実行できます。
SELECT * FROM 社員;
SELECT 部署名, 拠点 FROM 部署テーブル WHERE 部署名 = '営業部';
sql
ただし、以下のようなSQLは実行できません。
INSERT INTO 社員 (社員ID, 氏名, 所属部署, 給与) VALUES (5, '新入社員', '開発部', 300000);
DELETE FROM 社員 WHERE 社員ID = 1;
UPDATE 社員 SET 給与 = 500000 WHERE 社員ID = 1;
sql
app_userには、より様々なことができる権限を設定するとしたら、以下のようなSQLを実行します。
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE 社員 TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE 部署テーブル TO app_user;
sql
上記によりapp_userはSELECT、INSERT、UPDATE、DELETEを実行できる。
社員テーブルの氏名、所属部署列のみ更新できる権限をapp_userに設定する場合は以下のとおりのSQLとなる。
GRANT UPDATE (氏名, 所属部署) ON TABLE 社員 TO app_user;
sql
あらゆる権限を付与する場合には以下のようなALL PRIVILEGES句を使ったSQLを実行します。
GRANT ALL PRIVILEGES ON TABLE 社員 TO app_user;
GRANT ALL PRIVILEGES ON TABLE 部署テーブル TO app_user;
sql
このようなGRANTによる権限設定のみをできるようにするには
GRANT ALL PRIVILEGES ON TABLE 社員 TO report_user WITH GRANT OPTION;
sql
のようにWITH GRANT OPTIONという句をつけます。
CASE
表の中で表示する値をIF文を使って、条件に応じた値を表示するのに使います。
SELECT
氏名,
給与,
CASE
WHEN 給与 >= 350000 THEN '高給与'
WHEN 給与 >= 300000 THEN '中給与'
ELSE '低給与'
END AS 給与ランク
FROM
社員
ORDER BY
給与 DESC;
sql
上記の例では、新たに給与ランクという列を表示用のために新たに作り(表自体に列を追加するわけではない)、既存の列、給与の列の値によって、表示する値を決めています。給与が35万円以上なら高給与、それ以外の値の中で30万以上なら中給与、それ以外なら低給与と表示します。
結果として以下のような表の出力を得ます。
氏名 | 給与 | 給与ランク |
---|---|---|
佐藤花子 | 400000 | 高給与 |
鈴木一郎 | 350000 | 高給与 |
山田太郎 | 300000 | 中給与 |
田中美咲 | 280000 | 低給与 |
SELECT句の列の指定のところで、CASE WHEN 条件 THEN 表示値 ELSE 表示値 END AS 列名のような指定をします。列指定に複雑なキーワードを設定していると思えば良いです。
ウィンドウ関数
列の表示に関数を指定することで、GROUP BY で設定した範囲で集計したり OVER (PARTITION BY)句で設定したグループごとで集計したりすることができます。この時、列の指定値として記述する関数をウィンドウ関数と呼んでいます。さまざまなウィンドウ関数サンプルを示すために、これまでの社員テーブルを以下のように拡張したものとして説明したいと思います。
社員ID | 氏名 | 所属部署 | 給与 | 入社年度 | 評価点 |
---|---|---|---|---|---|
1 | 山田太郎 | 営業部 | 300000 | 2020 | 85 |
2 | 佐藤花子 | 開発部 | 400000 | 2018 | 92 |
3 | 鈴木一郎 | 営業部 | 350000 | 2019 | 88 |
4 | 田中美咲 | 総務部 | 280000 | 2021 | 78 |
5 | 高橋健太 | 開発部 | 420000 | 2019 | 95 |
6 | 伊藤美穂 | 営業部 | 300000 | 2020 | 80 |
7 | 小林大輔 | 開発部 | 380000 | 2020 | 90 |
AVG、SUM、OVER句を使った例
平均や合計を算出するウィンドウ関数です。集計グループはOVER句の中にPARTITION BY句を使って示すことで各行に全体やある列の何かの値ごとグループ化された値について関数で集計した結果を各行に示すことができます。
SELECT
氏名,
所属部署,
給与,
AVG(給与) OVER (PARTITION BY 所属部署) AS 部署平均給与,
SUM(給与) OVER (PARTITION BY 所属部署) AS 部署給与総額,
AVG(給与) OVER () AS 全体平均給与, -- PARTITION BY なしは全体に対して
SUM(給与) OVER () AS 全体給与総額 -- PARTITION BY なしは全体に対して
FROM
社員
ORDER BY
所属部署, 給与 DESC;
sql
上記のようなSQLを実行すると、以下のような表を得ることができます。
氏名 | 所属部署 | 給与 | 部署平均給与 | 部署給与総額 | 全体平均給与 | 全体給与総額 |
---|---|---|---|---|---|---|
高橋健太 | 開発部 | 420000 | 400000.00 | 1200000 | 352857.14 | 2470000 |
佐藤花子 | 開発部 | 400000 | 400000.00 | 1200000 | 352857.14 | 2470000 |
小林大輔 | 開発部 | 380000 | 400000.00 | 1200000 | 352857.14 | 2470000 |
鈴木一郎 | 営業部 | 350000 | 316666.67 | 950000 | 352857.14 | 2470000 |
山田太郎 | 営業部 | 300000 | 316666.67 | 950000 | 352857.14 | 2470000 |
伊藤美穂 | 営業部 | 300000 | 316666.67 | 950000 | 352857.14 | 2470000 |
田中美咲 | 総務部 | 280000 | 280000.00 | 280000 | 352857.14 | 2470000 |
AVG、SUM、OVER句を使わない例
OVER句を使わない場合は、1行にまとまった結果を得ることができます。
SELECT
SUM(給与) AS 全体給与総額,
AVG(給与) AS 全体平均給与,
COUNT(社員ID) AS 総社員数
FROM
社員;
sql
全体給与総額 | 全体平均給与 | 総社員数 |
---|---|---|
2470000 | 352857.14 | 7 |
OVER句を使わない場合はこのような集計表示になります。1行に集約しようとします。したがって、ある列ではOVER句をつかっているのにある列ではOVER句の指定がない場合には1行に集約しようとしているのに、一行に集約しないものを使おうとしているということで矛盾が生じ、SQLの実行はエラーになります。
AP データベース SQL基礎へ戻る。
AP データベースへ戻る。