この特集のトップページへ
>
Appendix B:SQLの基本文法
B.2 SELECT文
SELECT文は,指定したテーブルからレコードを取り出すときに利用する。SELECT文の書式は,次のとおりである。
SELECT 修飾子 フィールド名, フィールド名, … FROM テーブル名, テーブル名, …
WHERE 条件式
GROUP BY グループ化するフィールド名, グループ化するフィールド名, …
HAVING 条件式
UNION ほかのSELECT文
ORDER BY 並び替えるフィールド名, 並び替えるフィールド名, …
B.2.1 基本書式
SELECT文は少々複雑なので,まずは簡単な構文から説明する。最も単純な構文は,次のようなものである。
SELECT フィールド名, フィールド名, … FROM テーブル名
この書式は,指定されたテーブルに含まれるレコードから指定されたフィールドを返すものである。たとえば,Table B-2に示したSampleTableというテーブルからIDという名前のフィールドとNAMEという名前のフィールドを取得するには,次のようにする。
SELECT ID, NAME FROM SampleTable
なお,フィールド名に“*”を指定することもできる。その場合には,テーブルに含まれるすべてのフィールドを返すことを意味する。
SELECT * FROM SampleTable
また,フィールド名は,テーブルに登録した名前以外のフィールド名として取得することもできる。そのためには,“AS 取得後のフィールド名”とする。たとえば,次のようにした場合,取得したIDフィールドをmyIDという名前で参照できるようになる(ADODB.Recordsetオブジェクトから取得する場合には,ADODB.Recordsetオブジェクト.Fields("myID").Valueとして取得できるということである)。
SELECT ID AS myID FROM SampleTable
ASを使って別名を指定するという方法は,演算するときによく使われる。たとえば,Table B-3のようなSalesRecordというテーブルを考える。
Table B-3 SalesRecordテーブル
PRODUCT | PRICE | NUMBER |
パソコン | \100,000 | 5 |
ラジオ | \5,.000 | 3 |
プリンタ | \30,000 | 10 |
このとき,次のようにすると,PRODUCT,PRICE,NUMBERのほかに,単価×数量の値をTOTALというフィールドとして取得することができる(Table B-4)。
SELECT PRODUCT, PRICE, NUMBER, PRICE*NUMBER AS TOTAL FROM SalesRecord
Table B-4 SELECT文の結果
PRODUCT | PRICE | NUMBER | TOTAL |
パソコン | \100,000 | 5 | \500,000 |
ラジオ | \5,.000 | 3 | \15,000 |
プリンタ | \30,000 | 10 | \300,000 |
B.2.2 条件を絞る
“SELECT フィールド名, フィールド名,
… FROM テーブル名”で返されるレコードは,テーブルに含まれる全レコードである。全レコードではなく,特定の条件を満たすレコードのみを取得したい場合には,SELECT文に“WHERE 条件式”を指定する。
SELECT フィールド名, フィールド名, …, FROM テーブル名 WHERE 条件式
たとえば,Table B-2に示したSampleTableというテーブルから,IDフィールドの値が5より大きいレコードだけを返すには,次のようにする。
SELECT * FROM SampleTable WHERE ID > 5
条件式は,ANDやORを組み合わせて,複数の条件を指定することもできる。たとえば,Table B-2に示したSampleTableというテーブルから,IDフィールドの値が5より大きく,かつ10より小さいレコードだけを返すには,次のようにする。
SELECT * FROM SampleTable WHERE (ID > 5) AND (ID < 10)
また,文字列を比較するときには,Likeという特別な演算子を使い,ワイルドカード文字で指定することもできる。たとえば,次のようにすると,SampleTableというテーブルに含まれるレコードのうち,TELフィールドの値が“03”で始まるものだけを返すことができる。
SELECT * FROM SampleTable WHERE TEL Like '03*'
Like演算子で使われるワイルドカード文字は,データベースエンジンによって異なるので,利用する場合にはデータベースエンジンのリファレンスマニュアルで確認してほしい。
B.2.3 並び替える
特定のフィールドで昇順または降順に並べ替えてレコードを取り出したいときには,SELECT文に“ORDER BY 並び替えたいフィールド名”を指定する。
○昇順(小さいもの順)で並び替えたいとき
SELECT フィールド名, フィールド名, … FROM テーブル名
WHERE 条件式 ORDER BY 並び替えたいフィールド名
※“WHERE 条件式”は省略可能である。
○降順(大きいもの順)で並べ替えたいとき
SELECT フィールド名, フィールド名, … FROM テーブル名
WHERE 条件式 ORDER BY 並び替えたいフィールド名 DESC
※“WHERE 条件式”は省略可能である。
すると,指定した並び替えたいフィールド名の順序で並び替えられ,レコードが返される。なお,ORDER BYの後ろには,複数のフィールド名をカンマで区切って列挙することもできる。その場合には,指定された先頭のフィールド名から順に並び替えられたものが返される。
B.2.4 重複を省く
SELECT文を実行した結果,格納されているレコードの状態や条件式によっては,すべてのフィールドの値がまったく同じレコードが戻されることがある。通常,重複したレコードは,重複した数だけ取り出されるのだが,場合によっては重複を取り除きたいこともある。
その場合には,SELECT文のすぐ次にDISTINCTを指定する。
SELECT DISTINCT フィールド名, フィールド名, … FROM テーブル名 〜
すると,重複した部分は1つにまとめられて返される。
B.2.5 グループ化と集計
唐突だが,Table B-5のようなSalesというテーブルを考える。このテーブルは,地域ごとの売り上げを記録したテーブルである。
Table B-5 Salesテーブル
AREA | PRODUCT | SALES |
東京 | パソコン | \1,000,000 |
東京 | テレビ | \500,000 |
東京 | ラジオ | \10,000 |
大阪 | パソコン | \2,000,000 |
大阪 | テレビ | \700,000 |
大阪 | ラジオ | \20,000 |
名古屋 | パソコン | \1,500,000 |
名古屋 | テレビ | \300,000 |
名古屋 | ラジオ | \15,000 |
このテーブルに記録されたレコードから,AREAごとの売り上げの合計(SALESフィールドの合計)を算出したいとする。このような場合に使うのが,集計関数である。
SQLには,Table B-6に示す集計関数が用意されている。
Table B-6 集計関数
関数名 | 解説 |
Ave | 平均値を求める |
Count | レコード数を求める |
Min | 最小値を求める |
Max | 最大値を求める |
Sum | 総和を求める |
たとえば,“Sum(SALES) AS TOTAL”とすると,SALESフィールドの値の合計がTOTALというフィールドとして取得できる。ただし,集計関数を使うには,どのフィールド項目でまとめて集計するのかをデータベースエンジン側に伝える必要がある。それを指定するのが,“GROUP BY グループ化するフィールド名”である。たとえば,次のように“GROUP BY AREA”として,AREAというフィールドでまとめて集計するSQL文を実行したとき,その結果はTable B-7のようになる。
SELECT AREA, Sum(SALES) AS TOTAL FROM Sales GROUP BY AREA
Table B-7 AREAでまとめた集計結果
AREA | TOTAL |
東京 | \1,510,000 |
大阪 | \2,720,000 |
名古屋 | \1,815,000 |
もし,PRODUCTごとにまとめたいのであれば,次のようにすればよい(Table B-8)。
SELECT PRODUCT, Sum(SALES) AS TOTAL FROM Sales GROUP BY PRODUCT
Table B-8 PRODUCTでまとめた集計結果
PRODUCT | TOTAL |
パソコン | \4,500,000 |
テレビ | \1,500,000 |
ラジオ | \45,000 |
ここでは,GROUP BY以降に1つのフィールド名を指定する例しか示していないが,必要があればカンマで区切ってフィールド名を列挙し,複数のフィールドでグループ化することもできる。
ところで,Table B-7において,TOTALが200万円以上の地域のレコードだけを取り出したいという場合を考える。その場合には,次のように“HAVING 条件式”を使う。
SELECT AREA, Sum(SALES) AS TOTAL FROM Sales HAVING TOTAL >= 2000000
“WHERE 条件式”と”HAVING 条件式”は,似ているが,その動作は異なる。“WHERE 条件式”は,集計まえ(GROUP BYで指定されたグループ化がされるまえ)にその条件が判断される。一方の,“HAVING 条件式”は,集計したあとにその条件が判断される。
B.2.6 WHEREを使ったテーブルの連結
次に,複数のテーブルを連結した結果を返すことを考える。ここにCustomerテーブルとOrderテーブルという2つのテーブルがあるとする(Table B-9,Table B-10)。この2つのテーブルは,CustomerテーブルのIDフィールドとOrderテーブルのCustomerIDフィールドで関連付けられているとする。つまり,Orderテーブル内のCustomerIDフィールドの値が1のレコードは,CustomerテーブルでIDフィールドに値1が割り当てられているレコードの注文を意味するものとする。
Table B-9 Customerテーブル
ID | NAME | TEL |
1 | Fumitaka Osawa | 0466-xx-xxxx |
2 | Hitoshi Yamamoto | 03-xxxx-xxxx |
3 | Noboru Nakamura | 045-xxx-xxxx |
Table B-10 Orderテーブル
ID | CustomerID | PRODUCT | PRICE |
1 | 2 | パソコン | \100,000 |
2 | 1 | テレビ | \50,000 |
3 | 3 | ラジオ | \5,000 |
4 | 1 | パソコン | \100,000 |
ここで,CustomerテーブルとOrderテーブルを結び付け,Table B-11のような結果を取得したいとする。
Table B-11 Table B-9とTable B-10を結び付けた結果
NAME | TEL | PRODUCT | PRICE |
Hitoshi Yamamoto | 03-xxxx-xxxx | パソコン | \100,000 |
Fumitaka Osawa | 0466-xx-xxxx | テレビ | \50,000 |
Noboru Nakamura | 045-xxx-xxxx | ラジオ | \5,000 |
Fumitaka Osawa | 0466-xx-xxxx | パソコン | \100,000 |
Table B-11は,OrderテーブルのCustomerIDフィールドの値を調べ,Customerテーブル内から該当するレコードを探し,NAMEフィールドとTELフィールドを引き出して,それを連結したものである。
これをSQL文で表現すると,次のようになる。
SELECT NAME, TEL, PRODUCT, PRICE FROM Customer, Order
WHERE Customer.ID = Order.CustomerID
このように,複数のテーブルを連結して結果を得るには,FROMの部分に複数のテーブルをカンマで区切って列挙し,“WHERE 条件式”のところで,それらのテーブルを連結する条件を示せばよい。
なお,上記のSQL文では,“WHERE 条件式”の部分が,“WHERE ID = CustomerID”ではなく,“WHERE Customer.ID = Order.CustomerID”となっている点に注意してほしい。もし“WHERE ID = CustomerID”とすると,この条件として指定したIDは,Customerテーブルに含まれるIDフィールドを指しているのか,それともOrderテーブルに含まれるIDフィールドを指しているのか,データベースエンジンが判断できなくなってしまう。複数のテーブルに同じ名前のフィールドが含まれるときには,“テーブル名.フィールド名”のようにピリオドで連結して記述し,どのテーブルに含まれるフィールドなのかを明示的に指定する必要がある(なお,“WHERE Customer.ID = CustomerID”とするのはかまわない。CustomerIDフィールドは,Orderテーブルにしか含まれていないからである)。
この“テーブル名.フィールド名”という書式は,“WHERE 条件式”だけでなく,SELECTのすぐあとに記載するフィールド名の列挙部分などにも使われる。
ところで,テーブルを連結する方法は,これだけではない。より細かい連結をしたければ,INNER JOIN,LEFT JOIN,RIGHT JOINを用いることになる。しかし,本稿ではそこまで踏み込まないので,必要に応じてデータベースエンジンのリファレンスマニュアルなどを参照してほしい。
B.2.7 UNIONを使ったテーブルの合成
テーブルを結合するのではなく,テーブルを連結したいこともある。テーブルを連結する場合には,UNIONで複数のSELECT文をつなげればよい。
たとえば,次の2つのSELECT文があるとする。
1)SELECT field1, field2 FROM TABLE1
2)SELECT field3, field4 FROM TABLE2
このとき,この2つのSELECT文の結果を合成するには,次のようにUNIONでつなげる。
SELECT field1, field2 FROM TABLE1 UNION field3, field4 FROM TABLE2
このとき,結果は左から,field1,field2,field3,field4の順に並ぶ。
Appendix B 3/6 | ||
本文のトップへ | Appendix Bのトップへ |