この特集のトップページへ
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

 このとき,次のようにすると,PRODUCTPRICENUMBERのほかに,単価×数量の値を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

 条件式は,ANDORを組み合わせて,複数の条件を指定することもできる。たとえば,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-9Table 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-9Table 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 JOINLEFT JOINRIGHT 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

 このとき,結果は左から,field1field2field3field4の順に並ぶ。

prev Appendix B 3/6 next
本文のトップへ | Appendix Bのトップへ