SQLのSELECT文を分かりやすい例で理解する
この記事では、SQLのSELECT文について理解し、実践で活用できるようにするための方法を表や具体例を多用して分かりやすく解説しています。
SELECT文の基本構文SELECT文の基本的な使い方GROUP BY句, HAVING句の具体的な使い方表の結合(JOIN)JOIN句の具体的な使い方USING句で表を結合する方法問い合わせ結果の集合集合演算子の具体的な使い方サブクエリ(副問い合わせ)WHERE句での副問い合わせIN句での副問い合わせFROM句での副問い合わせ
SELECT文の基本構文
文は、データベースから必要な情報を取り出すための基本的なコマンドです。
一般的なSELECT文の構文は以下の通りです。
以下の「句」を組み合わせることで、クエリを作成します。
SELECT | 取得したい列を指定。「*」を指定すると全ての列を取得可能。 |
---|---|
FROM | データを取得する対象のテーブル名を指定。 |
WHERE | 指定した条件に合致する行のみ取得。 |
GROUP BY | 指定した列のデータが同一の行をグループ化。 |
HAVING | の結果に対してさらに条件を絞り込むために使用。 |
ORDER BY | 取得したデータの並び順を指定。は昇順、は降順。 |
LIMIT | 取得するデータの件数を制限。 |
SELECT文での処理の実行順序は、
FROM→ JOIN → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
SELECT文の基本的な使い方
以下のusersテーブルを例にSELECT文の基本的な使い方をみていきます。
user_id | name | age | city |
---|---|---|---|
1 | Taro | 25 | Tokyo |
2 | Hanako | 30 | Osaka |
3 | Jiro | 28 | Kyoto |
ageが30以上のユーザーを取得したい場合は、以下のクエリを使用します。
出力結果は以下の通りです。
user_id | name | age | city |
---|---|---|---|
2 | Hanako | 30 | Osaka |
GROUP BY句, HAVING句の具体的な使い方
以下のtestテーブルより、チームごとの合計スコアを計算し、100点以上のチームのみ表示する例を見て行きます。
id | team | name | score |
---|---|---|---|
1 | A | Alice | 120 |
2 | A | Bob | 20 |
3 | B | Chris | 50 |
4 | B | Daniel | 60 |
5 | C | Eric | 20 |
6 | C | Fiona | 10 |
SQL文と出力結果は以下の通りです。
SQL文:
出力結果:
team | SUM(score) |
---|---|
A | 140 |
B | 110 |
表の結合(JOIN)
複数のテーブルから関連するデータを結合して取得することもできます。
[表1]と[表2]を結合するためのSQL構文は以下の通りです。
[結合タイプ] の部分は結合の種類を表し、2つのテーブルをどのように結合するかを指定します。
以下の5種類の内、1つを指定します。
INNER JOIN (内部結合) | 両方の表にあるデータのみを結合 |
---|---|
LEFT OUTER JOIN (左外部結合) | 左の表にしかない行+共通にある行を結合 |
RIGHT OUTER JOIN (右外部結合) | 右の表にしかない行+共通にある行を結合 |
FULL OUTER JOIN (完全外部結合) | 左の表にしかない行+共通にある行+右の表にしかない行を結合 |
CROSS JOIN (交差結合) | 2つのテーブルの全ての組み合わせ |
JOIN句の具体的な使い方
以降では、5つの各結合タイプ(, , , , の具体的な使い方と実行結果を紹介していきます。
以下の2つのテーブルを用いた例で説明します。
users テーブル:
user_id | name |
---|---|
1 | Alice |
2 | Bob |
orders テーブル:
order_no | user_id | price |
---|---|---|
100 | 2 | 2000 |
101 | 3 | 3000 |
INNER JOINで内部結合する例
まず、によって内部結合する例です。「INNER」は省略可能です。
出力結果は以下の通りです。
両方に共通するを持つ行だけを返します。
user_id | name | price |
---|---|---|
2 | Bob | 2000 |
LEFT OUTER JOINで左外部結合する例
続いて同じ2つの表を、によって左外部結合する例です。
SQL文は以下の通りです。「OUTER」は省略可能です。
出力結果は以下の通りです。
usersテーブルの全ての行を返し、条件に一致する右側のテーブルの行を追加します。
右側に該当する行がない場合は、NULLで埋められます。
user_id | name | price |
---|---|---|
1 | Alice | NULL |
2 | Bob | 2000 |
RIGHT OUTER JOINで右外部結合する例
続いて同じ2つの表を、によって右外部結合する例です。
SQL文は以下の通りです。「OUTER」は省略可能です。
出力結果は以下の通りです。
右側のordersテーブルの全ての行を返し、条件に一致する左側のテーブルの行を追加します。
左側に該当する行がない場合は、NULLで埋められます。
user_id | name | price |
---|---|---|
2 | Bob | 2000 |
3 | NULL | 3000 |
FULL OUTER JOINで完全外部結合する例
続いて同じ2つの表を、によって完全外部結合する例です。
SQL文は以下の通りです。「OUTER」は省略可能です。
出力結果は以下の通りです。
user_id | name | price |
---|---|---|
1 | Alice | NULL |
2 | Bob | 2000 |
3 | NULL | 3000 |
CROSS JOINで交差結合する例
続いて同じ2つの表を、によって交差結合する例です。
SQL文は以下の通りです。
出力結果は以下の通りです。
2つのテーブルの全ての組み合わせを返します。
name | price |
---|---|
Alice | 2000 |
Alice | 3000 |
Bob | 2000 |
Bob | 3000 |
USING句で表を結合する方法
上で説明したON句の代わりに、USING句を使うこともできます。
SQL ServerやAccessなどではUSING句は使用できないので注意です。
以下の2つの表を例に具体的な使用例を紹介します。
users テーブル:
user_id | name |
---|---|
1 | Alice |
2 | Bob |
orders テーブル:
order_no | user_id | price |
---|---|---|
100 | 2 | 2000 |
101 | 3 | 3000 |
まず最初に比較対象として、ON句を使った場合のSQL文を示します。
出力結果は以下の通りです。
SELECTで「*」を指定すると、両方の表のuser_idの列が重複して表示されてしまいます。
user_id | name | order_no | user_id | price |
---|---|---|---|---|
2 | Bob | 100 | 2 | 2000 |
次にUSING句を使い、2つのテーブルをuser_idを基に結合するためのSQL文は以下の通りです。
出力結果は以下のようになり、user_idの重複がなくなります。
user_id | name | order_no | price |
---|---|---|---|
2 | Bob | 100 | 2000 |
問い合わせ結果の集合
2つのSELECT文の結果を行単位で比較してまとめることもできます。
SQLの構文は以下の通りで、2つのSELECT文を「集合演算子」と呼ばれるワードでつなげます。
集合演算子には以下の3種類のものが指定できます。
ALLを付けると重複した行を残すことができます。
集合演算子 | 説明 |
---|---|
UNION [ALL] | 複数のクエリの結果を結合。(和集合) |
INTERSECT [ALL] | 複数のクエリ結果の共通部分を取得。(共通集合) |
EXCEPT [ALL] | 最初のクエリ結果から、他のクエリ結果を引いたものを取得。(差集合) Oracleの場合は「EXCEPT」の代わりに「MINUS」と記述し、「ALL」は指定できない。 |
集合演算子の具体的な使い方
例えば、次のusersテーブルとcustomersテーブルがあるとします。
usersテーブル:
user_id | name |
---|---|
1 | Taro |
2 | Hanako |
customersテーブル:
customer_id | name |
---|---|
1 | Jiro |
2 | Hanako |
UNION句で和集合を出す例
SQL文:
出力結果:
name |
---|
Taro |
Hanako |
Jiro |
INTERSECT句で共通集合をを出す例
usersテーブルとcustomersテーブルに共通して存在するデータのみが表示されます。
SQL文:
出力結果:
name |
---|
Hanako |
EXCEPT句で差集合をを出す例
2つのテーブルに共通して存在するHanakoが、usersテーブルから削除されて出力されます。
SQL文:
出力結果:
name |
---|
Taro |
サブクエリ(副問い合わせ)
サブクエリ(副問い合わせ)とは、あるSQL文の中で、別のSQLクエリをネストする手法です。
通常、サブクエリは括弧で囲まれ、メインクエリに対して値を提供したり、フィルタリング条件を提供したりします。
副問い合わせを記述できる箇所:
SELECT句、FROM句、WHERE句、HAVING句
WHERE句での副問い合わせ
副問い合わせを使用して、特定の条件を満たすデータを選択する例です。
例えば、最も高い給料をもらっている社員を探したい場合、次のようなクエリを使用できます。
このクエリでは、内側のが最大給料を取得し、それを外側のの条件として使用しています。これにより、最大給料をもらっている社員の情報を取得できます。
IN句での副問い合わせ
複数の条件を満たすレコードを選ぶ場合、句と副問い合わせを組み合わせることができます。例えば、特定の部門で働いている社員のリストを取得するには、次のように書けます。
ここでは、テーブルから東京にある部門のIDを取得し、その部門に所属する社員を選択しています。これにより、複数の部門にまたがる情報を簡単に取得できます。
FROM句での副問い合わせ
副問い合わせは句にも使用でき、仮想的なテーブルを作成することが可能です。
例えば、平均給料より高い給料をもらっている社員を探すために次のようなクエリが使えます。
このクエリでは、まず平均給料より高い社員のリストをサブクエリで作成し、それを句で呼び出してという仮想テーブルを作っています。この仮想テーブルをさらに利用することで、読みやすいクエリを作ることが可能です。