-- 基本的なSELECT文
SELECT 氏名, 年齢, 住所 FROM 顧客;
-- 全列を選択
SELECT * FROM 商品;
-- 計算式を含む選択
SELECT 商品名, 単価, 在庫数, 単価 * 在庫数 AS 在庫金額
FROM 商品;
-- 条件付き抽出
SELECT 氏名, メールアドレス
FROM 顧客
WHERE 年齢 >= 20 AND 都道府県 = '東京都';
-- NULL値を持つレコードを検索
SELECT * FROM 顧客 WHERE 退会日 IS NULL;
-- NULL値を持たないレコードを検索
SELECT * FROM 社員 WHERE 上司ID IS NOT NULL;
-- 部門ごとの平均給与を求める
SELECT 部門, AVG(給与) AS 平均給与
FROM 社員
GROUP BY 部門;
-- 複数列でのグループ化
SELECT 部門, 役職, COUNT(*) AS 人数
FROM 社員
GROUP BY 部門, 役職;
-- 集計結果に条件を設定
SELECT 商品カテゴリ, SUM(売上) AS 総売上
FROM 販売
GROUP BY 商品カテゴリ
HAVING SUM(売上) > 1000000;




SELECT 商品名, 価格,
(SELECT AVG(価格) FROM 商品 AS s
WHERE s.カテゴリ = 商品.カテゴリ) AS カテゴリ平均価格
FROM 商品;
SELECT 社員名,
(SELECT 部署名 FROM 部署
WHERE 部署.部署ID = 社員.部署ID) AS 所属部署
FROM 社員;
-- 単一行の挿入
INSERT INTO 顧客 (氏名, 電話番号, メール)
VALUES ('山田太郎', '03-1234-5678', 'yamada@example.com');
-- 複数行の挿入
INSERT INTO 商品 (商品名, 価格, カテゴリ)
VALUES
('スマートフォンA', 80000, '電子機器'),
('ノートブックB', 120000, '電子機器'),
('ヘッドフォンC', 25000, 'オーディオ');
-- クエリ結果の挿入
INSERT INTO 売上集計 (カテゴリ, 合計金額, 集計日)
SELECT カテゴリ, SUM(価格 * 数量), CURRENT_DATE
FROM 注文明細 JOIN 商品 ON 注文明細.商品ID = 商品.ID
GROUP BY カテゴリ;
UPDATE 社員
SET 給与 = 給与 * 1.1
WHERE 部署 = '営業部';
UPDATE 商品
SET 在庫数 = 在庫数 - 10,
最終更新日 = CURRENT_DATE
WHERE 商品ID = 12345;
UPDATE 顧客
SET 累計購入額 = (
SELECT SUM(金額)
FROM 注文
WHERE 注文.顧客ID = 顧客.ID
);
-- テーブル作成
CREATE TABLE 顧客 (
顧客ID INT PRIMARY KEY,
氏名 VARCHAR(100) NOT NULL,
電話番号 VARCHAR(20),
メールアドレス VARCHAR(100) UNIQUE,
登録日 DATE DEFAULT CURRENT_DATE
);
-- テーブル変更
ALTER TABLE 顧客
ADD 住所 VARCHAR(200),
MODIFY 電話番号 VARCHAR(30);
-- インデックス作成
CREATE INDEX idx_顧客_氏名 ON 顧客(氏名);
CREATE UNIQUE INDEX idx_顧客_メール ON 顧客(メールアドレス);
-- テーブル削除
DROP TABLE 古い顧客;
CREATE PROCEDURE 注文処理(
IN 顧客ID INT,
IN 商品ID INT,
IN 数量 INT
)
BEGIN
DECLARE 在庫数 INT;
-- 在庫確認
SELECT 在庫 INTO 在庫数
FROM 商品 WHERE ID = 商品ID;
IF 在庫数 >= 数量 THEN
-- 注文登録
INSERT INTO 注文(顧客ID, 注文日)
VALUES(顧客ID, CURRENT_DATE);
-- 在庫更新
UPDATE 商品
SET 在庫 = 在庫 - 数量
WHERE ID = 商品ID;
END IF;
END;
CREATE FUNCTION 消費税計算(
価格 DECIMAL(10,2)
) RETURNS DECIMAL(10,2)
BEGIN
RETURN 価格 * 0.1;
END;
-- 関数の使用例
SELECT 商品名, 価格,
消費税計算(価格) AS 消費税,
価格 + 消費税計算(価格) AS 税込価格
FROM 商品;
-- 更新日時を自動記録するトリガー
CREATE TRIGGER 顧客更新記録
AFTER UPDATE ON 顧客
FOR EACH ROW
BEGIN
INSERT INTO 変更履歴 (
テーブル名, レコードID, 変更日時, 変更内容
) VALUES (
'顧客', NEW.顧客ID, NOW(),
CONCAT('更新: ', OLD.氏名, ' → ', NEW.氏名)
);
END;
-- 整合性確認トリガー
CREATE TRIGGER 在庫チェック
BEFORE INSERT ON 注文明細
FOR EACH ROW
BEGIN
DECLARE 在庫数 INT;
SELECT 在庫 INTO 在庫数
FROM 商品 WHERE 商品ID = NEW.商品ID;
IF 在庫数 < NEW.数量 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '在庫不足エラー';
END IF;
END;
// PHP例(危険なコード)
$username = $_POST['username'];
$query = "SELECT * FROM users
WHERE username = '$username'";
// ユーザーが username に
// ' OR 1=1 -- を入力すると全ユーザー情報が漏洩
// PHP例(安全なコード)
$username = $_POST['username'];
$stmt = $db->prepare(
"SELECT * FROM users
WHERE username = ?"
);
$stmt->bind_param("s", $username);
$stmt->execute();



-- 問題1: 以下のテーブルから、部門ごとの平均給与と
-- 全社平均との差額を計算するクエリを作成してください
-- 社員(社員ID, 氏名, 部門ID, 給与)
-- 部門(部門ID, 部門名)
-- 解答例:
WITH 全社平均 AS (
SELECT AVG(給与) AS 平均給与
FROM 社員
)
SELECT
d.部門名,
AVG(s.給与) AS 部門平均給与,
AVG(s.給与) - (SELECT 平均給与 FROM 全社平均) AS 全社平均との差額
FROM
社員 s
JOIN 部門 d ON s.部門ID = d.部門ID
GROUP BY
d.部門ID, d.部門名
ORDER BY
全社平均との差額 DESC;