MySQLの基本クエリにおけるSELECT構文の詳細な解説
SELECTはSQLで最も頻繁に使用される文であり、データ取得のほぼすべてはここから始まります。
このレッスンでは、SELECT文の基本的な構文と一般的な操作について、体系的に解説します。
graph TB
A[SELECT Inquiry Process] --> B[FROM<br/>Specify a data source]
B --> C[WHERE<br/>Conditional Filtering]
C --> D[GROUP BY<br/>Grouping]
D --> E[HAVING<br/>Filter Groups]
E --> F[SELECT<br/>Select a field]
F --> G[DISTINCT<br/>Remove duplicates]
G --> H[ORDER BY<br/>Sort]
H --> I[LIMIT<br/>Pagination]
1. 学習内容
- SELECT: フィールドの選択(すべて/指定/エイリアス)
- WHERE句によるフィルタリング
- 重複を削除するための DISTINCT クエリ
- ORDER BY による並べ替え
- LIMIT ページネーション
2. ある報告書の裏にある実話
(1) 課題:処理すべきデータが多すぎる
データアナリストは、10万件の注文データの中から「先月の注文額が最も多かった顧客10人」を特定する必要があります。
手動でページをスクロールする?Excelでフィルタリングする?どちらもあまり効率的ではありません。
(2) SELECT の解決策
SQL
SELECT
customer_name,
SUM(amount) AS total_spent
FROM orders
WHERE order_date >= '2026-06-01' AND order_date < '2026-07-01'
GROUP BY customer_name
ORDER BY total_spent DESC
LIMIT 10;
メリット: 1回のSQLクエリで、数秒以内に結果が返されます。
3. SELECT文の基本構文
▶ 例:すべてのフィールドをクエリする
SQL
-- Query all fields(Use with caution in production environments)
SELECT * FROM employees;
-- Query a Specific Field(Recommendations)
SELECT first_name, last_name, salary FROM employees;
▶ 例:フィールドのエイリアス
SQL
-- AS Set Aliases for Keywords
SELECT
first_name AS first_name,
last_name AS last_name,
salary AS salary
FROM employees;
-- (Omit) AS (same result)
SELECT first_name first_name, last_name last_name FROM employees;
-- If an alias contains spaces, it must be enclosed in quotation marks.
SELECT first_name AS 'First Name' FROM employees;
出力:
TEXT
+--------+--------+--------+
| first_name | last_name | salary |
+--------+--------+--------+
| John | Smith | 5000 |
| Jane | Doe | 6000 |
+--------+--------+--------+
▶ 例:式の計算
SQL
-- Calculate Annual Salary
SELECT
first_name,
salary,
salary * 12 AS annual_salary
FROM employees;
-- String Concatenation
SELECT
CONCAT(first_name, ' ', last_name) AS full_name
FROM employees;
4. WHERE句によるフィルタリング
▶ 例:基本的な条件
SQL
-- Equal Value Query
SELECT * FROM employees WHERE department = 'Engineering';
-- Non-equality query
SELECT * FROM employees WHERE salary != 5000;
-- Range Query
SELECT * FROM employees WHERE salary BETWEEN 4000 AND 8000;
-- List Query
SELECT * FROM employees WHERE department IN ('Sales', 'Marketing', 'HR');
-- Fuzzy Search
SELECT * FROM employees WHERE first_name LIKE 'J%';
-- NULL Search
SELECT * FROM employees WHERE manager_id IS NULL;
▶ 例:条件の組み合わせ
SQL
-- AND Combination
SELECT * FROM employees
WHERE department = 'Engineering' AND salary > 6000;
-- OR Combination
SELECT * FROM employees
WHERE department = 'Sales' OR department = 'Marketing';
-- Mixed Combinations(Use parentheses to specify precedence)
SELECT * FROM employees
WHERE (department = 'Sales' OR department = 'Marketing')
AND salary > 5000;
-- NOT Negate
SELECT * FROM employees WHERE NOT (department = 'HR');
5. DISTINCT による重複排除
▶ 例:重複削除クエリ
SQL
-- Single-Field Duplicate Removal
SELECT DISTINCT department FROM employees;
-- Multi-field combination dedup
SELECT DISTINCT department, job_title FROM employees;
-- Count the number of unique entries
SELECT COUNT(DISTINCT department) AS dept_count FROM employees;
出力:
TEXT
+-------------+
| department |
+-------------+
| Engineering |
| Sales |
| Marketing |
| HR |
+-------------+
6. ORDER BY による並べ替え
▶ 例:ソートされたクエリ
SQL
-- Single-field ascending order (Default)
SELECT * FROM employees ORDER BY salary ASC;
-- Single-field descending order
SELECT * FROM employees ORDER BY salary DESC;
-- Sorting by Multiple Fields
SELECT * FROM employees
ORDER BY department ASC, salary DESC;
-- Sort by expression
SELECT
first_name,
salary,
salary * 12 AS annual
FROM employees
ORDER BY annual DESC;
-- Sort by field position (2nd column)
SELECT first_name, salary FROM employees ORDER BY 2 DESC;
出力:
TEXT
+------------+--------+
| first_name | salary |
+------------+--------+
| Charlie | 8000 |
| Jane | 6000 |
| John | 5000 |
+------------+--------+
7. LIMIT によるページネーション
▶ 例:ページネーション付きクエリ
SQL
-- Query the first 10 rows
SELECT * FROM employees LIMIT 10;
-- Skip the first 10 rows, take 10 rows (Page 2)
SELECT * FROM employees LIMIT 10 OFFSET 10;
-- Shorthand: LIMIT offset, count
SELECT * FROM employees LIMIT 10, 10; -- Page 2
-- Page numbering formula: LIMIT (page-1) * pageSize, pageSize
-- Page 3, 20 rows per page
SELECT * FROM employees LIMIT 40, 20;
▶ 例:ページネーションの実践
SQL
-- Page 1
SELECT * FROM products ORDER BY id LIMIT 0, 10;
-- Page 2
SELECT * FROM products ORDER BY id LIMIT 10, 10;
-- Page 3
SELECT * FROM products ORDER BY id LIMIT 20, 10;
8. クエリの完全な例
▶ 例:包括的なクエリ
SQL
-- Query the top 5 highest-paid employees in Engineering
SELECT
CONCAT(first_name, ' ', last_name) AS employee_name,
department,
salary,
hire_date
FROM employees
WHERE department = 'Engineering'
AND salary IS NOT NULL
ORDER BY salary DESC
LIMIT 5;
-- Query employees hired in 2025, statistics by department
SELECT
department,
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary
FROM employees
WHERE hire_date BETWEEN '2025-01-01' AND '2025-12-31'
GROUP BY department
ORDER BY avg_salary DESC;
❓ よくある質問
Q SELECT * にはどのような問題がありますか?
A 本番環境では
* の使用を避けてください。すべてのフィールドを返すことは、ネットワーク帯域幅とメモリを無駄にするだけでなく、テーブル構造の変更によってコードが動作しなくなる可能性があります。必要なフィールドを明示的に指定してください。Q WHERE と HAVING の違いは何ですか?
A WHERE はグループ化前に行をフィルタリングするのに対し、HAVING はグループ化後にグループをフィルタリングします。WHERE は集計関数と併用できませんが、HAVING は併用できます。
Q
ORDER BYを複数のフィールドで使用する際の並べ替えの優先順位はどのようになりますか?A 結果はまず最初のフィールドで並べ替えられ、最初のフィールドで同順位の場合、次に2番目のフィールドで並べ替えられます。
Q LIMITのオフセットが大きい場合にパフォーマンスが低下する場合はどうすればよいですか?
A オフセットが大きい場合(LIMIT 100000, 10など)は、パフォーマンスが著しく低下します。カーソルによるページネーションに切り替えてください:
WHERE id > last_id LIMIT 10。Q DISTINCT はパフォーマンスに影響しますか?
A DISTINCT は重複を削除するためにソートが必要となるため、大規模なデータセットを扱う場合、処理が遅くなることがあります。重複を削除する必要がない場合は、DISTINCT を使用しないでください。
📖 まとめ
- SELECT はデータを取得します。
*はすべてのフィールドを取得します。フィールド名を指定することをお勧めします。 - WHERE フィルタ条件;
= / != / < / > / BETWEEN / LIKE / IN / IS NULLに対応 - DISTINCT は重複を削除します。単一のフィールドまたは複数のフィールドの組み合わせに対して適用できます。
- ORDER BY: 並べ替え;ASC = 昇順(デフォルト)、DESC = 降順
- LIMIT ページネーション、
LIMIT offset, countまたはLIMIT count OFFSET offset - カーソルによるページネーションを使用して、オフセットの大きいページネーションを最適化する
📝 練習問題
-
基本問題(難易度 ⭐):
employeesテーブルから、給与が 5,000 を超える従業員を検索し、結果を給与の降順で並べ替え、最初の 5 行のみを表示してください。 -
上級問題(難易度 ⭐⭐):
ordersテーブルから 2026 年の注文データを取得し、月ごとの注文数と合計金額を算出し、結果を月ごとに並べ替えてください。 -
課題(難易度:⭐⭐⭐):1ページあたり20件のレコードを返すページネーション付きクエリを実装してください。5ページ目のデータをクエリし、大きな
LIMITオフセットを使用する場合と、カーソルベースのページネーションを使用する場合のパフォーマンスの違いを比較してください。



