SQLのSELECT文を分かりやすい例で理解する

この記事では、SQLのSELECT文について理解し、実践で活用できるようにするための方法を表や具体例を多用して分かりやすく解説しています。
 

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_idnameagecity
1Taro25Tokyo
2Hanako30Osaka
3Jiro28Kyoto
ageが30以上のユーザーを取得したい場合は、以下のクエリを使用します。
出力結果は以下の通りです。
user_idnameagecity
2Hanako30Osaka

GROUP BY句, HAVING句の具体的な使い方

以下のtestテーブルより、チームごとの合計スコアを計算し、100点以上のチームのみ表示する例を見て行きます。
idteamnamescore
1AAlice120
2ABob20
3BChris50
4BDaniel60
5CEric20
6CFiona10
SQL文と出力結果は以下の通りです。
SQL文:
出力結果:
team SUM(score)
A140
B110

表の結合(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_idname
1Alice
2Bob
orders テーブル:
order_nouser_idprice
10022000
10133000
 
INNER JOINで内部結合する例
まず、によって内部結合する例です。「INNER」は省略可能です。
出力結果は以下の通りです。 両方に共通するを持つ行だけを返します。
user_idnameprice
2Bob2000
 
LEFT OUTER JOINで左外部結合する例
続いて同じ2つの表を、によって左外部結合する例です。
SQL文は以下の通りです。「OUTER」は省略可能です。
出力結果は以下の通りです。 usersテーブルの全ての行を返し、条件に一致する右側のテーブルの行を追加します。 右側に該当する行がない場合は、NULLで埋められます。
user_idnameprice
1AliceNULL
2Bob2000
 
RIGHT OUTER JOINで右外部結合する例
続いて同じ2つの表を、によって右外部結合する例です。
SQL文は以下の通りです。「OUTER」は省略可能です。
出力結果は以下の通りです。 右側のordersテーブルの全ての行を返し、条件に一致する左側のテーブルの行を追加します。 左側に該当する行がない場合は、NULLで埋められます。
user_idnameprice
2Bob2000
3NULL3000
 
FULL OUTER JOINで完全外部結合する例
続いて同じ2つの表を、によって完全外部結合する例です。
SQL文は以下の通りです。「OUTER」は省略可能です。
出力結果は以下の通りです。
user_idnameprice
1AliceNULL
2Bob2000
3NULL3000
 
CROSS JOINで交差結合する例
続いて同じ2つの表を、によって交差結合する例です。
SQL文は以下の通りです。
出力結果は以下の通りです。 2つのテーブルの全ての組み合わせを返します。
nameprice
Alice2000
Alice3000
Bob2000
Bob3000

USING句で表を結合する方法

上で説明したON句の代わりに、USING句を使うこともできます。
SQL ServerやAccessなどではUSING句は使用できないので注意です。
 
以下の2つの表を例に具体的な使用例を紹介します。
users テーブル:
user_idname
1Alice
2Bob
orders テーブル:
order_nouser_idprice
10022000
10133000
まず最初に比較対象として、ON句を使った場合のSQL文を示します。
出力結果は以下の通りです。 SELECTで「*」を指定すると、両方の表のuser_idの列が重複して表示されてしまいます。
user_idnameorder_nouser_idprice
2Bob10022000
次にUSING句を使い、2つのテーブルをuser_idを基に結合するためのSQL文は以下の通りです。
出力結果は以下のようになり、user_idの重複がなくなります。
user_idnameorder_noprice
2Bob1002000

問い合わせ結果の集合

2つのSELECT文の結果を行単位で比較してまとめることもできます。 SQLの構文は以下の通りで、2つのSELECT文を「集合演算子」と呼ばれるワードでつなげます。
 
集合演算子には以下の3種類のものが指定できます。 ALLを付けると重複した行を残すことができます。
集合演算子説明
UNION [ALL]複数のクエリの結果を結合。(和集合)
INTERSECT [ALL]複数のクエリ結果の共通部分を取得。(共通集合)
EXCEPT [ALL]最初のクエリ結果から、他のクエリ結果を引いたものを取得。(差集合) Oracleの場合は「EXCEPT」の代わりに「MINUS」と記述し、「ALL」は指定できない。

集合演算子の具体的な使い方

例えば、次のusersテーブルとcustomersテーブルがあるとします。
usersテーブル:
user_idname
1Taro
2Hanako
customersテーブル:
customer_idname
1Jiro
2Hanako
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句での副問い合わせ

副問い合わせは句にも使用でき、仮想的なテーブルを作成することが可能です。 例えば、平均給料より高い給料をもらっている社員を探すために次のようなクエリが使えます。
このクエリでは、まず平均給料より高い社員のリストをサブクエリで作成し、それを句で呼び出してという仮想テーブルを作っています。この仮想テーブルをさらに利用することで、読みやすいクエリを作ることが可能です。