SQL: 基本クエリ
図書館に行って本を探したいと想像してください。すべての本を家に持ち帰るわけではありません — 代わりに司書にこう言います:「2020年以降に出版されたSF小説を探したいのですが、出版日の新しい順に並べて、最初の5冊を見せてください。」このプロセスは、SQLクエリの主要なステップに対応します:データの選択、条件のフィルタリング、ソート、数量の制限。
前のレッスンでは、データベースとテーブルの作成、データの挿入方法を学びました。このレッスンでは、データベースから必要なデータを正確にクエリする方法を学びます。
1. 基本概念
(1) SELECTステートメント
SELECTはSQLで最もよく使われるステートメントで、データベーステーブルからデータを取得するために使用します。基本構造は:
SELECT カラム1, カラム2, ...
FROM テーブル名;
SELECTの後にクエリする列を指定FROMの後にクエリ対象のテーブルを指定- 各SQLステートメントはセミコロン
;で終わる
(2) 特定の列とすべての列のクエリ
特定の列をクエリ(推奨):
SELECT name, salary FROM employees;
すべての列をクエリ:
SELECT * FROM employees;
*を使用する代わりに必要な列名を明示的に指定することを推奨します。これによりクエリ効率が向上し、コードがより明確になります。
(3) WHERE条件フィルタリング
WHERE句はレコードをフィルタリングするために使用され、条件を満たす行のみを返します:
SELECT カラム1, カラム2
FROM テーブル名
WHERE 条件;
(4) 比較演算子
| 演算子 | 説明 | 例 |
|---|---|---|
= |
等しい | salary = 50000 |
<> または != |
等しくない | status <> 'Inactive' |
> |
より大きい | salary > 50000 |
< |
より小さい | age < 30 |
>= |
以上 | salary >= 50000 |
<= |
以下 | age <= 30 |
(5) 論理演算子:AND / OR
AND:すべての条件が真である必要があるOR:少なくとも1つの条件が真である必要がある
SELECT name, salary, department_id
FROM employees
WHERE salary > 50000 AND department_id = 1;
SELECT name, salary, department_id
FROM employees
WHERE department_id = 1 OR department_id = 2;
ANDとORが混在する場合、ANDの方が優先されます。括弧()を使用して優先順位を明確にし、あいまいさを避けましょう。
(6) IN / BETWEEN / LIKE
IN — セット内の任意の値にマッチ:
SELECT name, department_id
FROM employees
WHERE department_id IN (1, 2, 3);
BETWEEN — 範囲内の値にマッチ(境界値を含む):
SELECT name, salary
FROM employees
WHERE salary BETWEEN 40000 AND 80000;
LIKE — あいまい文字列マッチング:
%は任意の数の文字にマッチ(ゼロを含む)_はExactly1文字にマッチ
-- 名前が「J」で始まる従業員
SELECT name FROM employees WHERE name LIKE 'J%';
-- 名前が4文字で「John」で始まる従業員
SELECT name FROM employees WHERE name LIKE 'John_';
(7) ORDER BYソート
ORDER BYは結果セットのソートに使用されます:
ASC:昇順(デフォルト、省略可能)DESC:降順
-- 給与が高い順にソート
SELECT name, salary
FROM employees
ORDER BY salary DESC;
-- 部署ID昇順、その後給与降順でソート
SELECT name, department_id, salary
FROM employees
ORDER BY department_id ASC, salary DESC;
(8) LIMIT行数制限
LIMITは返されるレコード数を制限するために使用されます:
-- 最初の5件のみ返す
SELECT name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5;
-- 最初の5件をスキップし、次の5件を返す(ページネーション)
SELECT name, salary
FROM employees
ORDER BY salary DESC
LIMIT 5 OFFSET 5;
LIMITは通常ORDER BYと併用します。そうしない場合、返されるレコードの順序は不定です。
2. 基本構文/使い方
(1) クエリステートメントの完全な構造
SELECT カラム1, カラム2, ...
FROM テーブル名
WHERE 条件
ORDER BY カラム [ASC|DESC]
LIMIT 件数 [OFFSET オフセット];
句の記述順序は厳密に守る必要があります:
| 順序 | 句 | 目的 |
|---|---|---|
| 1 | SELECT |
クエリする列を指定 |
| 2 | FROM |
ソーステーブルを指定 |
| 3 | WHERE |
行をフィルタリング |
| 4 | ORDER BY |
結果をソート |
| 5 | LIMIT |
返される行数を制限 |
(2) よく使うテクニック
-- エイリアスで列名を見やすくする
SELECT name AS employee_name, salary AS employee_salary
FROM employees;
-- 重複値を除去
SELECT DISTINCT department_id
FROM employees;
-- SELECTで式を使用
SELECT name, salary, salary * 12 AS annual_salary
FROM employees;
- エイリアスには日本語を使用できますが、チーム協力のため英語を推奨します
DISTINCTは選択されたすべての列の組み合わせに基づいて重複を除去します- 式は元のデータを変更しません。クエリ結果の表示にのみ影響します
(3) サンプル
(4) サンプル:特定の部署の従業員をクエリ
要件:部署IDが1のすべての従業員の名前と給与を、給与が高い順にソートしてクエリします。
SELECT name, salary
FROM employees
WHERE department_id = 1
ORDER BY salary DESC;
期待される出力:
+----------+--------+
| name | salary |
+----------+--------+
| John | 85000 |
| Bob | 62000 |
| Alice | 55000 |
+----------+--------+
説明:
WHERE department_id = 1は部署IDが1の行のみを保持ORDER BY salary DESCは給与を降順でソート- 結果には
nameとsalary列のみ含まれる
(5) サンプル:複数条件クエリ
要件:給与が60000から90000の間で、部署IDが1または2の従業員をクエリします。名前、部署ID、給与を表示。部署ID昇順、その後給与降順でソート。
SELECT name, department_id, salary
FROM employees
WHERE salary BETWEEN 60000 AND 90000
AND department_id IN (1, 2)
ORDER BY department_id ASC, salary DESC;
期待される出力:
+----------+---------------+--------+
| name | department_id | salary |
+----------+---------------+--------+
| John | 1 | 85000 |
| Bob | 1 | 62000 |
| Jane | 2 | 75000 |
+----------+---------------+--------+
説明:
BETWEEN 60000 AND 90000は給与範囲をフィルタリングIN (1, 2)は部署をフィルタリングANDは2つの条件を結合- まず部署IDで昇順ソートし、同じ部署内では給与で降順ソート
(6) サンプル:あいまいクエリとページネーション
要件:名前に「J」を含む従業員を見つけ、入社日の新しい順にソートし、2番目から3番目のレコードのみ表示。
SELECT name, hire_date, salary
FROM employees
WHERE name LIKE '%J%'
ORDER BY hire_date DESC
LIMIT 2 OFFSET 1;
期待される出力:
+--------+------------+--------+
| name | hire_date | salary |
+--------+------------+--------+
| Jane | 2022-03-15 | 68000 |
| Julia | 2021-08-20 | 52000 |
+--------+------------+--------+
説明:
LIKE '%J%'は名前の任意の位置に「J」を含むレコードにマッチORDER BY hire_date DESCは入社日を新しい順にソートLIMIT 2 OFFSET 1は最初のレコードをスキップし、2番目と3番目を返す(すなわち、1ページ2件の2ページ目)
3. シナリオ
(1) シナリオ1:給与範囲で高給従業員をフィルタリング
人事部門は給与が70000以上の従業員リストのエクスポートが必要です。名前、部署、給与を含み、給与が高い順にソートします。
SELECT e.name AS employee_name,
d.name AS department_name,
e.salary AS salary
FROM employees e
JOIN departments d ON e.department_id = d.id
WHERE e.salary > 70000
ORDER BY e.salary DESC;
注意事項:
JOINを使用して部署テーブルを関連付け、部署名を取得(後のレッスンで詳しく説明)eとdはテーブルエイリアスで、記述を簡素化- エイリアスは説明的な名前を使用し、出力をより明確に
(2) シナリオ2:ページネーション付き従業員リスト
Webアプリケーションの従業員リストページは1ページに10件表示します。ユーザーがページ3をクリックした場合、最初の20件をスキップして21〜30件目を表示する必要があります。
-- ページ3、1ページ10件
SELECT id, name, department_id, salary
FROM employees
ORDER BY id ASC
LIMIT 10 OFFSET 20;
ページネーション式:OFFSET = (ページ番号 - 1) × 1ページあたりのレコード数
| ページ | LIMIT | OFFSET |
|---|---|---|
| ページ1 | 10 | 0 |
| ページ2 | 10 | 10 |
| ページ3 | 10 | 20 |
▶ サンプル
SELECT name, age FROM users WHERE age >= 18 ORDER BY age DESC LIMIT 10;
❓ よくある質問
SELECT *と列名を指定する違いは何ですか?WHEREでエイリアスは使えますか?BETWEENは境界値を含みますか?LIKEは大文字小文字を区別しますか?📖 まとめ
このレッスンでは、SQLクエリの主要スキルをカバーしました:
- SELECT — クエリする列を指定。
*ですべての列をクエリ - WHERE — 条件で行をフィルタリング。比較演算子(
=、>、<、<>、>=、<=)をサポート - 論理演算子 —
AND(両方)、OR(いずれか)。括弧で優先順位を制御 - IN — セット内の任意の値にマッチ
- BETWEEN — 範囲内の値にマッチ(境界値を含む)
- LIKE — あいまいマッチング。
%は複数文字にマッチ、_は単一文字にマッチ - ORDER BY — ソート。
ASC昇順(デフォルト)、DESC降順 - LIMIT / OFFSET — 返される行を制限し、ページネーションを実現
クエリステートメントの記述順序:SELECT → FROM → WHERE → ORDER BY → LIMIT
📝 練習問題
(1) 演習1:基本クエリ
departmentsテーブルのすべてのレコードをクエリし、nameとlocation列のみ表示してください。
(2) 演習2:条件フィルタリングとソート
employeesテーブルで、給与が60000以上かつ2022年1月1日以降に入社した従業員をクエリしてください。名前、給与、入社日を表示し、給与降順でソートしてください。
(3) 演習3:総合クエリ
employeesテーブルで、部署IDが1または3で、名前が「J」で始まらない従業員をクエリしてください。名前、部署ID、給与を表示。部署ID昇順、給与降順でソート。最初の3件のみ返してください。
次のレッスン:データ操作:INSERT、UPDATE、DELETE