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?

SQLをクエスト式でAIと学習した話

Posted at

はじめに

SQLを「クエスト形式」で学習したら、めちゃくちゃ理解が深まったので共有します!

実際にDockerでPostgreSQLを立ち上げて、ECサイト風のサンプルデータで実践しました。

使用した環境

  • Docker + PostgreSQL 15
  • db-ui(SQLをブラウザで実行できるツール)
  • サンプルDB:ユーザー、カテゴリ、商品、注文、注文詳細の5テーブル

データベース構造

users (ユーザー) ─────┐                                                                              
                      ├──→ orders (注文) ──→ order_items (注文詳細)                                  
categories (カテゴリ) ─┴──→ products (商品) ──────────┘                                              
                                                                           ```                                                                                            
                                                                                                     
## Chapter 1: SELECT基礎                                                                             
                                                                                                     
```sql                                                                                               
-- 全データ取得                                                                                      
SELECT * FROM users                                                                                  
                                                                                                     
-- 特定カラムだけ                                                                                    
SELECT username, email FROM users                                                                    
                                                                                                     
学び: SELECT で取りたいカラムを、FROM でテーブルを指定。                                             

Chapter 2: WHERE(条件絞り込み)

  -- 条件で絞り込む                                                                                    
  SELECT * FROM users WHERE is_active = true                                                           
                                                                                                       
  -- 比較演算子                                                                                        
  SELECT * FROM products WHERE price >= 10000                                                          
                                                                                                       
  学び: >=(以上)と >(より大きい)の違いに注意!                                    ```              
                                                                                                       
  ---                                                                                                  
  Chapter 3: AND / OR(複数条件)                                                                      

-- 両方満たす
SELECT * FROM products WHERE price >= 10000 AND stock_quantity >= 30

-- どちらか満たす
SELECT * FROM orders WHERE status = 'completed' OR status = 'shipped'

-- IN を使うとスッキリ
SELECT * FROM orders WHERE status IN ('completed', 'shipped')
```

Chapter 4: ORDER BY & LIMIT

-- 高い順に並べる                                                                                    
SELECT * FROM products ORDER BY price DESC                                                           
                                                                                                     
-- 上位3件だけ                                                                                       
SELECT * FROM products ORDER BY price DESC LIMIT 3                                                   
                                                                                                     
-- 2番目を取得(OFFSETは0始まり)                                                                    
SELECT * FROM products ORDER BY price DESC LIMIT 1 OFFSET 1                                          
                                                                                                     
学び: OFFSET 1 で「1件スキップ」= 2番目から取得。                                                    

Chapter 5: 集計関数 ```

SELECT COUNT(*) FROM products -- 件数
SELECT MAX(price) FROM products -- 最大値
SELECT MIN(price) FROM products -- 最小値
SELECT SUM(total_amount) FROM orders -- 合計
SELECT AVG(price) FROM products -- 平均

---                                                                                                  
Chapter 6: GROUP BY                                                                                  

-- カテゴリごとの商品数
SELECT category_id, COUNT(*)
FROM products
GROUP BY category_id

-- 集計結果で絞り込み(HAVING)
SELECT category_id, COUNT()
FROM products
GROUP BY category_id
HAVING COUNT(
) >= 2

学び:

  • WHERE → グループ化「前」のフィルタ(個別の行)
  • HAVING → グループ化「後」のフィルタ(集計結果)
---                                                                                                  
Chapter 7: JOIN(最重要!)                                                                          

基本のJOIN

-- ユーザー名付きの注文一覧
SELECT * FROM orders
JOIN users ON orders.user_id = users.id

JOINのコツ

〇〇_id = 〇〇.id で繋ぐ!

user_id = users.id
category_id = categories.id
order_id = orders.id
product_id = products.id

主キー(PK)と外部キー(FK)
┌───────────────┬───────────────────────┬───────────────────────┐
│ 種類 │ 特徴 │ 例 │
├───────────────┼───────────────────────┼───────────────────────┤
│ 主キー (PK) │ 自動採番される id │ id SERIAL PRIMARY KEY │
├───────────────┼───────────────────────┼───────────────────────┤
│ 外部キー (FK) │ 「〇〇_id」という名前 │ user_id, category_id │
└───────────────┴───────────────────────┴───────────────────────┘
FKを持っている方 = 子 = 多の側

3テーブル結合

SELECT users.username, order_items.product_id, order_items.quantity
FROM orders
JOIN users ON orders.user_id = users.id
JOIN order_items ON order_items.order_id = orders.id

---                                                                                                  
Chapter 8: サブクエリ                                                         ```                  
                                                                                                     
-- 平均価格より高い商品                                                                              
SELECT * FROM products                                                                               
WHERE price > (SELECT AVG(price) FROM products)                                                      
                                                                                                     
-- 注文したことがあるユーザー                                                                        
SELECT * FROM users                                                                                  
WHERE id IN (SELECT user_id FROM orders)                                                             
                                                                                                     
-- 注文されたことがない商品                                                                          
SELECT * FROM products                                                                               
WHERE id NOT IN (SELECT product_id FROM order_items)                                                 
                                                                                                     
JOINとサブクエリの使い分け                                                                           
┌──────────────────────────────────┬────────────┐                                                    
│           やりたいこと           │    使う    │                                                    
├──────────────────────────────────┼────────────┤                                                    
│ 2つのテーブルを合体して見たい    │ JOIN       │                                                    
├──────────────────────────────────┼────────────┤                                                    
│ 他テーブルの値で絞り込みたいだけ │ サブクエリ │                                                    
└──────────────────────────────────┴────────────┘                                                    

Chapter 9: DISTINCT / LIKE / BETWEEN ```

-- 重複を除く
SELECT DISTINCT category_id FROM products

-- あいまい検索
SELECT * FROM users WHERE last_name LIKE '%田%' -- 「田」を含む
SELECT * FROM products WHERE name LIKE '%ン' -- 「ン」で終わる

-- 範囲指定

SELECT * FROM products WHERE price BETWEEN 5000 AND 50000                                            
┌──────────┬────────────┐                                                                            
│ パターン │    意味    │                                                                            
├──────────┼────────────┤                                                                            
│ '%田%'   │ 田を含む   │                                                                            
├──────────┼────────────┤                                                                            
│ '%ン'    │ ンで終わる │                                                                            
├──────────┼────────────┤                                                                            
│ 'ン%'    │ ンで始まる │                                                                            
└──────────┴────────────┘                                                  

Chapter 10: INSERT / UPDATE / DELETE

INSERT(追加)                                                                                       
                                                                                                     
INSERT INTO categories (name, description)                                                           
VALUES ('食品', '食料品、飲料、お菓子など')                                                          
                                                                                                     
UPDATE(更新)                                                                                       
                                                                                                     
-- 特定の行を更新                                                                                    
UPDATE products SET price = 3500 WHERE id = 3                                                        
                                                                                                     
-- 計算して更新                                                                                      
UPDATE products                                                                                      
SET stock_quantity = stock_quantity + 10                                                             
WHERE category_id = 1                                                                                
                                                                                                     
注意:WHEREを忘れると全行更新される!                                                                
                                                                                                     
DELETE(削除)                                                                                       
                                                                                                     
DELETE FROM orders WHERE status = 'pending'                                                          
                                                                                                     
注意:WHEREを忘れると全行削除される!                                                                
                                                                                                     
外部キー制約                                                                                         
                                                                                                     
エラー: update or delete on table "orders" violates foreign key constraint                           
                                                                                                     
FK(外部キー)がある = 勝手に消せない!                                                              
                                                                                                     
参照されてる親は、子が残ってると削除エラーになる。これはデータの整合性を守る仕組み。                 
                                                                                                     
-- 解決方法:先に参照してる方を消す                                                                  
DELETE FROM order_items                                                                              
WHERE order_id IN (SELECT id FROM orders WHERE status = 'pending')                                   
                                                                                                     
DELETE FROM orders WHERE status = 'pending'                                                          

まとめ

習得したスキル                                                                                       
┌──────────┬─────────────────────────────────┐                                                       
│ カテゴリ │              内容               │                                                       
├──────────┼─────────────────────────────────┤                                                       
│ 読む     │ SELECT, WHERE, JOIN, サブクエリ │                                                       
├──────────┼─────────────────────────────────┤                                                       
│ 集計     │ COUNT, SUM, AVG, GROUP BY       │                                                       
├──────────┼─────────────────────────────────┤                                                       
│ 書く     │ INSERT, UPDATE, DELETE          │                                                       
├──────────┼─────────────────────────────────┤                                                       
│ 概念     │ PK/FK, 1:多, 外部キー制約       │                                                       
└──────────┴─────────────────────────────────┘                                                       

重要な気づき

  1. スキーマを確認する重要性: テーブル名だけでなく、カラム定義を見ないと関係性はわからない
  2. FKの見分け方: 〇〇_id があればそれがFK、参照先の 〇〇.id がPK
  3. JOINとサブクエリの使い分け: 両方のデータが欲しいならJOIN、条件だけならサブクエリ

おわりに

クエスト形式で学ぶと、間違えた時に「なぜ間違えたか」が明確になって理解が深まりました。

特にJOINとPK/FKの関係は、図で理解してから実際に書くとスッと入ってきます。

SQLは怖くない!実際に手を動かして学ぶのが一番です。


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?