データベース 第2部 データベース 4 データベースの照会処理


 

4 データベースの照会処理

4.1 照会処理(問合せ処理)

権限を付与された利用者は、許された範囲内で表に対してアクセスすることができます。照会(または問合せ)とは、表中のデータを読み取ることをいいます。


ACCESSでは …
次のような手順で「クエリ」を作成する。
  1. メニュー「作成」-「クエリデザイン」をクリックする。
  2. 表示された「テーブルの表示」で、照会したい表名を選択し、「追加」ボタンをクリックする(照会したい表が複数あれば繰り返す)。
  3. 追加し終えたなら、「閉じる」ボタンをクリックする。
  4. 「フィールド」、「抽出条件」などを設定する。
  5. メニュー「デザイン」-「表示」を「データシート ビュー」に変更して、結果を表示する。
また、メニュー「デザイン」-「表示」を変更することによって、デザイン画面とSQLの表示を切り替えることができる。
  • SQL を表示するには、メニュー「デザイン」-「表示」を「SQL ビュー」に変更する。
  • クエリデザインを表示するには、メニュー「デザイン」-「表示」を「デザイン ビュー」に変更する。

4.1.1 基本構文

表中のデータの読み取りは、関係データベースの処理の中で最も多く発生するデータ操作で、SQLでは「SELECT文」を用いて操作します。

なお、SQL文は Access で表示される形式で、右上には Access の QBE方式での定義方法を示しています。

データの読み取り
SELECT 列名    ← 取り出す列を指定する
  FROM 表名    ← 読み取る元となる表を指定する(クエリ名やかっこで囲ったSELECT文も指定できる)
      


(1) 全ての項目の検索

ACCESSの「クエリデザイン」
    
フィールド: 受注.*  
テーブル: 受注  
並べ替え:    
表示:    
抽出条件:    
または:    

SELECT 文節に続いて * を指定すると、すべての項目(列)を表示します。

例えば、SELECT文を次のように指示すると、読み取る表のすべての列を表の定義で指定した列の順序で表示します。

SELECT * FROM 受注
        

<表示結果>
受注番号受注年月日顧客番号受注合計
000012024/04/011001
\640,000
000022024/04/021006
\518,000
000032024/04/021003
\600,000
000042024/04/051001
\3,000

(2) 特定の項目の検索

ACCESSの「クエリデザイン」
    
フィールド: 受注番号受注合計 
テーブル: 受注受注 
並べ替え:    
表示:    
抽出条件:    
または:    

SELECT 文節に続いて 項目名(列名)を指定すると、指定した項目(列)を表示します。

このとき、SELECT 文節の列名間はカンマで区切り、列名は表示したい順序で指定します。FROM 文節の表名は、複数指定することもできますが、それは後述します。

例えば、「[受注]から、[受注番号]と[受注合計]を表示する」は、次のようになります。

SELECT 受注番号, 受注合計
  FROM 受注
      
<表示結果>
受注番号受注合計
00001
\640,000
00002
\518,000
00003
\600,000
00004
\3,000

ACCESSの「クエリデザイン」
    
フィールド: 受注番号式1: [受注合計]*1.08 
テーブル: 受注受注 
並べ替え:    
表示:    
抽出条件:    
または:    

また、計算結果を表示する場合は、列名に算術演算子を使った計算式を記述します。「[受注]から、[受注番号]と[受注合計]の 1.08 倍の金額を表示する」は、次のようになります(フィールドに単に 受注合計*1.08 と入力しても右図のように表示されます)。

SELECT 受注番号, [受注合計]*1.08 AS 式1
  FROM 受注
      
<表示結果>
受注番号式1
00001
691200
00002
559440
00003
648000
00004
3240

このとき、計算式を参照するために、[式1] という別名が(ACCESS によって自動的に)つけられますが、別名については後述します。また、[受注合計] というように [ ] がやはり自動的につけられます。これは、計算式の中において「列名」であることを明確にするためです。

ACCESSでは …
「クエリデザイン」では、フィールド欄の最初に "式1:" のように、新しい列名を指定する。また、例えば、AAA と記述した場合、文字列なのか列名なのかは自動的に判断されるが、正しく判断されないときは "文字列"、 [列名] のように明示する必要がある。

(3) ひとつ項目で重複するデータを除いた検索

ACCESSの「クエリデザイン」
    
フィールド: 受注年月日  
テーブル: 受注  
並べ替え:    
表示:    
抽出条件:    
または:    

例えば、「[受注]から[受注年月日]を表示する」は、次のようになります。

SELECT 受注年月日 FROM 受注
      
<表示結果>
受注年月日
2024/04/01
2024/04/02
2024/04/02
2024/04/05

この表示結果自体に誤りはないですが、同じ内容のレコードを重複して表示したくない場合もあります。その場合は、重複データを排除する DISTINCT を使用します。

SELECT DISTINCT 受注年月日 FROM 受注
      
<表示結果>
受注年月日
2024/04/01
2024/04/02
2024/04/05

ACCESSでは …
次のような手順でクエリに DISTINCT を指定する。
  1. (表が選択されていない状態で)メニュー「デザイン」-「プロパティシート」クリックし、「プロパティシート」を表示する。
  2. 表示された「プロパティシート」の「固有の値」を「はい」にする。

(4) 複数の項目で重複するデータを除いた検索

表示されるすべての項目で完全に一致した場合にのみ重複して表示したくないときも、同様に指定できます。

SELECT DISTINCT 受注年月日, 顧客番号 FROM 受注
      
<表示結果>
受注年月日顧客番号
2024/04/011001
2024/04/021003
2024/04/021006
2024/04/051001





例題 1
[商品]から、次のような表示結果を抽出するSQL文を作成してください。

<表示結果>
商品名単価
テレビ(液晶大型)
\200,000
テレビ(液晶小型)
\50,000
DVDレコーダ
\80,000
ラジオ
\3,000
冷蔵庫
\150,000
エアコン
\98,000



例題 2
次のSQL文を実行したときの表示結果を答えてください。

    SELECT DISTINCT 受注番号, 商品番号 FROM 受注明細
        


4.1.2 条件式照会

ある一定の条件に基づいた特定行の読み取りを、条件式照会といいます。特定行の指示は、SQLでは「WHERE」文節を用いて条件を指定します。

条件式照会
SELECT 列名
  FROM 表名
 WHERE 探索条件    ← どの行を選ぶかという条件式を指定する
    

探索条件は演算子を用いて、式の形式で記述されます。条件式に用いられる代表的な演算子には次のようなものがあります。

  • 比較演算子(関係演算子)
  • 論理演算子
  • 空白値用演算子
  • リスト値用の演算子
  • 文字列比較用演算子

(1) 比較演算子(関係演算子)

比較演算子は関係演算子ともいわれ、数値型・文字型を比較するための演算子です。

SQLでは、次のような演算子が用いられます。

  • =  等しい
  • >  より大きい
  • <  より小さい
  • >= 以上
  • <= 以下
  • != 等しくない
ACCESSでは …
等しくないは <> を指定する。

SQLでの構文は、次のような形式で指示します。

WHERE 列名 比較演算子 値 
      

この比較演算子を用いて、関係台数の選択と射影をSQLで指示すると次のようになります。

ACCESSの「クエリデザイン」
    
フィールド: 受注.*顧客番号 
テーブル: 受注受注 
並べ替え:    
表示:    
抽出条件:  "1001" 
または:    

例えば、「[受注]から[顧客番号]が 1001 の行を取り出す」は、次のようになります。

このとき、[顧客番号]は文字列型なので 1001 も引用符( ' または " )で囲み指定します。

SELECT * FROM 受注
 WHERE 顧客番号 = "1001"
      
受注
受注番号受注年月日顧客番号受注合計
000012024/04/011001
\640,000
000022024/04/021006
\518,000
000032024/04/021003
\600,000
000042024/04/051001
\3,000

<表示結果>
受注番号受注年月日顧客番号受注合計
000012024/04/011001
\640,000
000042024/04/051001
\3,000



┐
│
│
├┐
││
││
┘│選択
 │
 │探索条件に適合した
 │特定の行を取り出す
 │
 │
←┘
      

また、日付型の場合も引用符( ' または " )で囲み指定します。

ACCESSでは …
日付型はシャープ(#)で囲み指示する。
ただし、ACCESS が表示する SQL 文では、年月日が #月/日/年# と表示されるので注意が必要である。

また、年を2桁で指定した場合、0~29 は 2000年代、30~99 は 1900年代と解釈される。

ACCESSの「クエリデザイン」
    
フィールド: 受注番号受注年月日 
テーブル: 受注受注 
並べ替え:    
表示:    
抽出条件:  #2024/04/01# 
または:    

例えば、「[受注]から[受注年月日]が "2024/4/1" の[受注番号]を表示する」は、次のようになります。

SELECT 受注番号 FROM 受注
 WHERE 受注年月日 = #2024/04/01#
      





例題 3
「[受注明細]から、[数量]が 3未満の顧客の、[商品番号]と[受注小計]を表示する」というSQL文を作成してください。

<表示結果>
商品番号受注小計
A01
\400,000
S05
\6,000
S05
\3,000



例題 4
あるSQL文を実行したところ、次のような実行結果が表示されました。実行されたSQL文を作成してください。

<表示結果>
受注番号顧客番号
000021006
000031003



(2) 論理演算子

論理演算子はブール演算子ともいわれ、前述の比較演算子で示された条件式を組み合わせるときなどに用いられます。SQLでは、次の演算子が用いられます。

  • AND かつ
  • OR  または
  • NOT (否定)
ACCESSの「クエリデザイン」
    
フィールド: 受注.*顧客番号受注合計
テーブル: 受注受注受注
並べ替え:    
表示:    
抽出条件:  "1001">=600000
または:    

例えば、「[受注]から、[顧客番号]が 1001 で、[受注合計]が600,000円以上のレコードを表示する」は、次のようになります。

SELECT * FROM 受注
 WHERE 顧客番号 = "1001" AND 受注合計 >= 600000
      
<表示結果>
受注番号受注年月日顧客番号受注合計
000012024/04/011001
\640,000

ACCESSでは …
抽出条件を横並びに指定した場合、AND 条件になる。



ACCESSの「クエリデザイン」
    
フィールド: 受注.*顧客番号受注合計
テーブル: 受注受注受注
並べ替え:    
表示:    
抽出条件:  "1001" 
または:   >=600000

また、「[受注]から、[顧客番号]が 1001 、または[受注合計]が600,000円以上のレコードを表示する」は、次のように指定することができます。

SELECT * FROM 受注
 WHERE 顧客番号 = "1001" OR 受注合計 >= 600000
      
<表示結果>
受注番号受注年月日顧客番号受注合計
000012024/04/011001
\640,000
000032024/04/021003
\600,000
000042024/04/051001
\3,000

ACCESSでは …
抽出条件を縦並びに指定した場合、OR 条件になる。



●2つの値の間にあるデータを含むレコードの検索
ACCESSの「クエリデザイン」
   
フィールド: 受注番号受注合計
テーブル: 受注受注
並べ替え:   
表示:   
抽出条件:  >=600000 AND <=1000000
または:   

同じ項目(列)に複数の条件を付ける場合には次のようになります。


例えば、「[受注]から、[受注合計]が60,000円以上で、かつ1,000,000円以下の[受注番号]と[受注合計]を表示する」は、次のようになります。

SELECT 受注番号, 受注合計 FROM 受注
 WHERE 受注合計 >= 600000 AND 受注合計 <= 1000000
        
ACCESSの「クエリデザイン」
    
フィールド: 受注番号受注合計受注合計
テーブル: 受注受注受注
並べ替え:    
表示:    
抽出条件:  >=600000<=1000000
または:    
<表示結果>
受注番号受注合計
00001
\640,000
00003
\600,000


ACCESSでは …
抽出条件を横並びに指定した場合、AND 条件になるので、右上の二つは同じ意味になります。


また、SQLでは上記のような抽出条件の場合、BETWEEN述語を用いて指定することもできます。

WHERE 列名 BETWEEN 最小値 AND 最大値
        

ACCESSの「クエリデザイン」
   
フィールド: 受注番号受注合計
テーブル: 受注受注
並べ替え:   
表示:   
抽出条件:  BETWEEN 600000 AND 1000000
または:   

したがって、上記の「[受注]から、[受注合計]が600,000円以上で、かつ1,000,000円以下の商品の[受注番号]と[受注合計]を表示する」は、次のように指定することもできます。

SELECT 受注番号, 受注合計 FROM 受注
 WHERE 受注合計 BETWEEN 600000 AND 1000000
        





例題 5
次の①~③のSQL文を作成し、表示結果とともに答えてください。

[顧客]から、[顧客番号]が "1001" か "1006" の[顧客名]を表示する。
[受注明細]から、[商品番号]が "S05" かつ[数量]が 2個以上の[受注番号]と[受注小計]を表示する。
[受注]から、[受注合計]が 50万円台(500000~599999)の[顧客番号]を表示する。




例題 6
次の①~⑥のSQL文を実行した場合の表示結果を答えよ。なお、表示結果がない場合は「ない」と答えよ。

SELECT * FROM 受注明細
 WHERE 受注番号 = "00002" AND 商品番号 = "S05" AND 数量 < 3
SELECT * FROM 受注明細
 WHERE 受注番号 = "00002" OR 商品番号 = "S05" OR 数量 < 3
SELECT * FROM 受注明細
 WHERE 受注番号 = "00002" AND 商品番号 = "S05" OR 数量 < 3
SELECT * FROM 受注明細
 WHERE 受注番号 = "00002" AND (商品番号 = "S05" OR 数量 < 3)
SELECT * FROM 受注明細
 WHERE 受注番号 = "00002" OR 商品番号 = "S05" AND 数量 < 3
SELECT * FROM 受注明細
 WHERE (受注番号 = "00002" OR 商品番号 = "S05") AND 数量 < 3






(3) 空白値(NULL)用の演算子

NULL というのは、""(空の文字列)ではなく、値のないことをいいます。例えば、該当するものがないとか未定の場合です。

●NULLを含むレコードの検索

表中のデータで、空白値(NULL)が許されている場合、その空白値を検索条件とすることができます。その場合、SQLでは、Is Null を用います。

NULL を探索条件で使用する場合は、= Null ではなく、Is Null とすることに注意します。NULL は、値ではなく状態であるため、= Null とするとエラーになります。

ACCESSの「クエリデザイン」
    
フィールド: 顧客番号顧客名電話番号
テーブル: 顧客顧客 
並べ替え:    
表示:    
抽出条件:   Is Null
または:    

例えば、「[顧客]から、[電話番号]が空白値となっている[顧客番号]と[顧客名]を表示する」は、次のようになります。

SELECT 顧客番号, 顧客名 FROM 顧客
 WHERE 電話番号 Is Null
        

<表示結果>
顧客番号顧客名
1010広島商店株式会社


●NULLを含まないレコードの検索
ACCESSの「クエリデザイン」
    
フィールド: 顧客番号顧客名電話番号
テーブル: 顧客顧客顧客
並べ替え:    
表示:    
抽出条件:   Is Not Null
または:    

また、NULL ではないというのを探索条件にする場合には、Is Not Null を用います。

SELECT 顧客番号, 顧客名, 電話番号 FROM 顧客
 WHERE 電話番号 Is Not Null
      

<表示結果>
顧客番号顧客名電話番号
1001株式会社冨田貿易03-3256-XXX
1003宇宙商事株式会社03-5126-XXX
1006有限会社吉野物産06-6112-XXX

(4) リスト値用の演算子

NULL というのは、""(空の文字列)ではなく、値のないことを言う。例えば、該当するものがないとか未定の場合です。

●リストと一致するデータを含むレコードの検索

リストの値と一致するデータを含むレコードを検索する場合は、条件の項目(列)名の後に IN 述語を指定し、かっこ ( ) 内にリストの値を記述します。

ACCESSの「クエリデザイン」
   
フィールド: 受注番号受注合計
テーブル: 受注受注
並べ替え:   
表示:   
抽出条件: In ('00001', '00004') 
または:   

例えば、「[受注]から、[受注番号]が 00001 か 00004 であるレコードの[受注番号]と[受注合計]を表示する」は、次のようになります。

SELECT 受注番号, 受注合計 FROM 受注
 WHERE 受注番号 In ('00001', '00004')
        

<表示結果>
受注番号受注合計
00001
\640,000
00004
\3,000

●リストと一致しないデータを含むレコードの検索

リストの値のいずれとも一致しないデータを含むレコードを検索する場合は、条件の項目(列)名の後に NOT IN 述語を指定し、かっこ ( ) 内にリストの値を記述します。

ACCESSの「クエリデザイン」
   
フィールド: 受注番号受注合計
テーブル: 受注受注
並べ替え:   
表示:   
抽出条件: Not In ('00001', '00004') 
または:   

例えば、「[受注]から、[受注番号]が 00001 でも 00004 でもないレコードの[受注番号]と[受注合計]を表示する」は、次のようになります。

SELECT 受注番号, 受注合計 FROM 受注
 WHERE 受注番号 Not In ('00001', '00004')
        

<表示結果>
受注番号受注合計
00002
\518,000
00003
\600,000

(5) 文字列比較用の演算子

SQLでは、「~で始まる」「~で終わる」「途中に~を含む」といった文字列の比較には、LIKE述語を用います。実際の指定には、%(パーセント)または、_(アンダースコア)を用いて指示します。% は 0文字以上の文字列を表し、_ は 1文字を表します。

例えば、A で始まる文字列を表現するのに、次の2種類の指定方法があります。

A% : A で始まる文字列(何文字でもよい)
A__ : A で始まる3文字の文字列

それぞれ意味が異なるので注意が必要です。


ACCESSでは …
%、_ ではなく、*、? を使用する。
A* : A で始まる文字列(何文字でもよい)
A?? : A で始まる3文字の文字列

LIKE述語は文字列型の列に対してのみ使用できる。


ACCESSの「クエリデザイン」
    
フィールド: 商品番号商品名 
テーブル: 商品商品 
並べ替え:    
表示:    
抽出条件:  Like "ラ??" 
または:    

例えば、「[商品]から、[商品名]が 3文字で"ラ"から始まる商品の[商品番号]と[商品名]を取り出す」は、次のようになります。

SELECT 商品番号, 商品名 FROM 商品
 WHERE 商品名 Like "ラ??"
      
<表示結果>
商品番号商品名
S05ラジオ


ACCESSの「クエリデザイン」
    
フィールド: 商品番号商品名 
テーブル: 商品商品 
並べ替え:    
表示:    
抽出条件:  Like "*液晶*" 
または:    

また、例えば「[商品]から、[商品名]に "液晶"を含む商品の[商品番号]と[商品名]を取り出す」は、次のように指示することができる。

SELECT 商品番号, 商品名 FROM 商品
 WHERE 商品名 Like "*液晶*"
      
<表示結果>
商品番号商品名
A01テレビ(液晶大型)
A11テレビ(液晶小型)





例題 7
次の①、②のSQL文を作成し、表示結果とともに答えてください。

[受注明細]から、[商品番号]の2文字目が "1" の[商品番号]と[数量]を表示する。
[商品]から、[商品名]に "レ" が含まれる[商品番号]と[単価]を表示する。


4.1.3 データの集約と並べ替え

(1) グループ化と集約関数(列関数)

集約関数は列関数ともいわれ、グループ化された列データを処理する関数のことをいいます。代表的な集約関数には次のようなものがあります。

SUM(列名): 数値列に対して、合計を求める
AVG(列名): 数値列に対して、平均を求める
MIN(列名): 数値列に対して、最小値を求める
MAX(列名): 数値列に対して、最大値を求める
COUNT(列名): 条件に合う行数を求める(指定された列が NULL の行はカウントされない)
COUNT(*): 条件に合う行数を求める
COUNT(DISTINCT 列名): 重複を除いて、条件に合う行数を求める

ACCESSでは …
「クエリデザイン」では、* に対してカウントは設定できない(SQL文では Count(*)を設定できる)。

ACCESSでは …
COUNT(DISTINCT 列名) は使用できない。

これらの集約関数は、いずれも特定の列をもとに、特定グループの計算を行います。このときにSQLでは集約関数と、グループ化するための GROUP BY文節を組み合わせて指示します。


ACCESSの「クエリデザイン」
    
フィールド: 商品番号数量 
テーブル: 受注明細受注明細 
集計: グループ化合計 
並べ替え:    
表示:    
抽出条件:    
または:    

例えば、「[受注明細]から、[商品番号]ごとの[数量]の合計を求めて表示する」は、次のようになります。

SELECT 商品番号, Sum(数量) FROM 受注明細
 GROUP BY 商品番号
      

ACCESSでは …
「クエリデザイン」に「集計」欄を表示するには、メニューの[デザイン]-[集計]をクリックします。

受注明細
受注番号商品番号数量受注小計
00001A01
2
\400,000
00001G02
3
\240,000
00002A11
10
\500,000
00002S05
2
\6,000
00003A01
3
\600,000
00004S05
1
\3,000
グループ化
│GROUP BY 商品番号
↓
          
商品番号数量
A01
2
3
A11
10
G02
3
S05
2
1
合計
  ┌────────┘Sum(数量)
  ↓
         
<表示結果>
商品番号Sum(数量)
A01
5
A11
10
G02
3
S05
3


GROUP BY 文節と WHERE 文節を同時に書いた場合は、まず WHERE 文節を実行し、その実行結果をもとに GROUP BY 文節を実行します。

ACCESSの「クエリデザイン」
    
フィールド: 受注番号数量商品番号
テーブル: 受注明細受注明細受注明細
集計: グループ化合計Where 条件
並べ替え:    
表示:    
抽出条件:   <>"S05"
または:    

例えば、「[受注明細]から、[商品番号]が "S05" を除いた[受注番号]ごとの[数量]の合計を求めて表示する」は、次のようになります。

SELECT 受注番号, Sum(数量) FROM 受注明細
 WHERE 商品番号 <> "S05"
 GROUP BY 受注番号
      


受注明細
受注番号商品番号数量受注小計
00001A01
2
\400,000
00001G02
3
\240,000
00002A11
10
\500,000
00002S05
2
\6,000
00003A01
3
\600,000
00004S05
1
\3,000
          

───────────→ WHERE 商品番号 <> "S05"
 
受注番号商品番号数量受注小計
00001A01
2
\400,000
00001G02
3
\240,000
00002A11
10
\500,000
00003A01
3
\600,000
 │グループ化
 │GROUP BY 受注番号
 ↓
              
受注番号数量
0001
2
3
0002
10
0003
3
    │合計
┌───┘Sum(数量)
↓
                
<表示結果>
受注番号Sum(数量)
0001
5
0002
10
0003
3


GROUP BY 文節と集約関数により求めた結果を選択条件として使用する場合には、HAVING 文節を使用します。

ACCESSの「クエリデザイン」
    
フィールド: 商品番号数量 
テーブル: 受注明細受注明細 
集計: グループ化カウント 
並べ替え:    
表示:    
抽出条件:  >=2 
または:    

例えば、「[受注明細]から、2件以上記録されている商品の[商品番号]と件数を表示する」は、次のようになります。

SELECT 商品番号, Count(数量) FROM 受注明細
 GROUP BY 商品番号
 HAVING Count(数量) >= 2


受注明細
受注番号商品番号数量受注小計
00001A01
2
\400,000
00001G02
3
\240,000
00002A11
10
\500,000
00002S05
2
\6,000
00003A01
3
\600,000
00004S05
1
\3,000
グループ化
│GROUP BY 商品番号
↓
       
商品番号数量
A01
2
3
A11
10
G02
3
S05
2
1
カウント
│Count(数量)    合計ではなく件数
商品番号Count(数量)
A01
2
A11
1
G02
1
S05
2
    │ 選択条件
┌───┘ HAVING Count(数量) >= 2
↓
       
<表示結果>
商品番号Count(数量)
A01
2
S05
2


また、集約関数により求めた列に新たに列名を付ける場合には、AS 文節を使用する。

ACCESSの「クエリデザイン」
    
フィールド: 商品番号最大: 数量 
テーブル: 受注明細受注明細 
集計: グループ化最大 
並べ替え:    
表示:    
抽出条件:    
または:    

例えば、「[受注明細]から、[商品番号]ごとの[数量]の最大値に "最大" という列名を付けて表示する」は次のようになる。

SELECT 商品番号, Max(数量) AS 最大 FROM 受注明細
 GROUP BY 商品番号
      


受注明細
受注番号商品番号数量受注小計
00001A01
2
\400,000
00001G02
3
\240,000
00002A11
10
\500,000
00002S05
2
\6,000
00003A01
3
\600,000
00004S05
1
\3,000
 │グループ化
 │GROUP BY 商品番号
 ↓
          
商品番号数量
A01
2
3
A11
10
G02
3
S05
2
1
    │最大
┌───┘Max(数量) AS 最大
↓
          
<表示結果>
商品番号最大
A01
3
A11
10
G02
3
S05
2

ACCESSでは …
「クエリデザイン」では、フィールド欄の最初に "最大:" のように、新しい列名を指定する。





例題 8
次の①~③のSQL文を作成し、表示結果とともに答えてください。

[受注明細]から、[商品番号]ごとの[数量]の平均を求めて、"平均"という列名を付け、[商品番号]とともに表示する。
[受注明細]から、[商品番号]が "A"で始まる商品ごとの件数を求めて、"件数"という列名を付け、[商品番号]とともに表示する。
[受注明細]から、[商品番号]ごとの[数量]の合計を求めて、"数量合計"という列名を付け、[数量]の合計が 5以上の[商品番号]と「数量合計」を表示する。



(2) データの整列

読み取った表の行は、必ずしも特定の順で並んでいるわけではありません。そこで、読みやすくするため、ある列の値の順序に並べて表示します。

SQLでは、並べ替えの順序を ORDER BY文節で指定します。

昇順の場合: ASC  (ASCending の略)
降順の場合: DESC (DESCending の略)

何も指定しない場合は、ASC が使用されます。昇順・降順は、数値型データであれば数値の大小、文字型データであれば文字コードの大小により判断されます。

ACCESSの「クエリデザイン」
    
フィールド: 受注番号受注合計 
テーブル: 受注受注 
並べ替え:  昇順 
表示:    
抽出条件:    
または:    

例えば、「[受注]から、[受注番号]と[受注合計]を[受注合計]の昇順に表示する」は、次のようになります。

SELECT 受注番号, 受注合計 FROM 受注
 ORDER BY 受注合計 ASC     ASC は省略してもよい
        

<表示結果>
受注番号受注合計
00004
\3,000
00002
\518,000
00003
\600,000
00001
\640,000

また、複数列を指定することにより、大分類、中分類、小分類といった並べ替えを行うこともできます。

ACCESSの「クエリデザイン」
    
フィールド: 受注明細.*商品番号受注小計
テーブル: 受注明細受注明細受注明細
並べ替え:  昇順降順
表示:    
抽出条件:    
または:    

例えば、「[受注明細]から、全データを「商品番号」の昇順、[受注小計]の降順に表示する」は、次のようになります。

SELECT * FROM 受注明細
 ORDER BY 商品番号 ASC, 受注小計 DESC
        

<表示結果>
受注番号商品番号数量受注小計
00003A01
3
\600,000
00001A01
2
\400,000
00002A11
10
\500,000
00001G02
3
\240,000
00002S05
2
\6,000
00004S05
1
\3,000




また、集約関数により求めた結果も並べ替えのキーとして使用することができます。

ACCESSの「クエリデザイン」
    
フィールド: 商品番号数量 
テーブル: 受注明細受注明細 
集計: グループ化合計 
並べ替え:  降順 
表示:    
抽出条件:    
または:    

例えば、「[受注明細]から、[商品番号]ごとの[数量]の合計を求めて、[数量]の大きい順に表示する」は、次のようになります。

SELECT 商品番号, Sum(数量) FROM 受注明細
 GROUP BY 商品番号
 ORDER BY Sum(数量) DESC
        

受注明細
受注番号商品番号数量受注小計
00001A01
2
\400,000
00001G02
3
\240,000
00002S05
2
\6,000
00002A11
10
\500,000
00003A01
3
\600,000
00004S05
1
\3,000
 │グループ化
 │GROUP BY 商品番号         
 ↓
              
商品番号数量
A01
2
3
G02
3
S05
2
1
A11
10
    │合計
┌───┘Sum(数量)
↓    ORDER BY Sum(数量) DESC
              
<表示結果>
商品番号Sum(数量)
A11
10
A01
5
S05
3
G02
3

この例では、ORDER BY文節に、Sum(数量) と記述されていますが、指定できない DBMS もあります(ACCESSは指定できます)。

この場合は、Sum(数量) の代わりに 2 と指定するようにします。2 とは SELECT文の何番目にある列を対象にしているかを示しています。Sum(数量) が SELECT文の 2番目にあるため、2 と指定しています。

SELECT 商品番号, Sum(数量) FROM 受注明細
 GROUP BY 商品番号
 ORDER BY 2 DESC
        



例題 9
次の①~③のSQL文を作成し、表示結果とともに答えよ。

[商品]から、[商品名]と「単価」を[商品名]の昇順に表示する。
[受注明細]から、[商品番号]と[数量]を[商品番号]の昇順、[数量]の降順に表示する。
[受注明細]から、各伝票ごとの[数量]の合計を求めて、合計の降順に[受注番号]と[数量]を表示する。




4.2 結合処理

結合処理(join)とは、複数の表の特定の列の値同士を結び付ける操作のことをいいます。そのためには、同一のデータ属性を持つ列が存在することが必要です。結合される複数の表は、主キー(基本キー)と外部キーで結合するのが一般的です。

例えば、「[受注明細]と[商品]を結合して、[商品番号]と[商品名]と[数量]を取り出す」は、両方の表に共通する[商品番号]を関連付けのための(リレーショナル)キーにします。

4.2.1 INNER JOIN

INNER JOIN文節は、両方の表に存在する[商品番号]の行のみを結び付けます。片方の表にしか存在しない[商品番号]は、結果として表示されません。この例では、[商品番号]Z01、Z11 は[商品]にはありますが、[受注明細]にはないため表示されません。

ACCESSの「クエリデザイン」
     
フィールド: 商品番号商品名数量 
テーブル: 商品商品受注明細 
並べ替え:     
表示:     
抽出条件:     
または:     
SELECT 商品.商品番号, 商品名, 数量
 FROM 商品 INNER JOIN 受注明細
   ON 商品.商品番号 = 受注明細.商品番号
      

[受注明細]と[商品]の間の線は、同じ名前の列同士の間で自動的に引かれますが、引かれない場合は、[受注明細]の[商品番号]を[受注明細]までドラッグすると引かれます。([受注]の[商品番号]上でマウスの左ボタンを押し、そのまま離さずに、[受注明細]上までマウスを移動させ、ボタンを離すと引かれます。)


受注明細
受注番号商品番号数量受注小計
00001A01
2
\400,000
00001G02
3
\240,000
00002S05
2
\6,000
00002A11
10
\500,000
00003A01
3
\600,000
00004S05
1
\3,000
商品
商品番号商品名単価
A01テレビ(液晶大型)
\200,000
A11テレビ(液晶小型)
\50,000
G02DVDレコーダ
\80,000
S05ラジオ
\3,000
Z01冷蔵庫
\150,000
Z11エアコン
\98,000
    └─────────┬────────────┘
              │結合
              ↓商品.商品番号 = 受注明細.商品番号
          
<表示結果>
商品番号商品名数量
A01テレビ(液晶大型)
2
A01テレビ(液晶大型)
3
A11テレビ(液晶小型)
10
G02DVDレコーダ
3
S05ラジオ
2
S05ラジオ
1



[商品番号]のように、結合するための二つの表には、同じ名称の列が存在する場合がありますが、その場合は「表名.列名」として区別します。


なお、上の例では、連結処理に、INNER JOIN文節を使用しましたが、すべてのDBMSで使用できるわけではありません。使用できない場合には、FROM文節にすべての表名を指示し、WHERE文節で結合する列名を等号( = )で結ぶ必要があります。

ACCESSの「クエリデザイン」
    
フィールド: 商品番号商品名数量
テーブル: 商品商品受注明細
並べ替え:    
表示:    
抽出条件: [受注明細].[商品番号]  
または:    
SELECT 商品.商品番号, 商品名, 数量
  FROM 受注明細, 商品
 WHERE 受注明細.商品番号 = 商品.商品番号
        


ACCESSでは …
「クエリデザイン」で、上記のようなSQLを作成する場合には、表同士をつないでいる線を削除(線を選んで右クリックして表示されるメニューから削除を選択)してから作成する必要がある(表同士が自動的に線によってつながれなかった場合は必要ない)。
また、[受注明細].[受注番号]のように、[ ] で囲まれているのは、表名や列名であることを示している。[ ] で囲まないと文字列として扱われてしまう。



このように、結合するための SELECT文は FROM文節で複数の表名を指定しますが、上の SQL文を次のように記述することもできます。

ACCESSの「クエリデザイン」
     
フィールド: 商品番号商品番号数量 
テーブル: YYY 
並べ替え:     
表示:     
抽出条件: [X].[商品番号]   
または:     
SELECT Y.商品番号, 商品名, 数量
  FROM 受注明細 AS X, 商品 AS Y
 WHERE Y.受注番号 = [X].[受注番号]
      

この例では、[受注明細]を[X]、[商品]を[Y]というように、別名を付けています。このときの X、Y を相関名といいます。表名が長いときなどに指定します。


ACCESSでは …
「クエリデザイン」では、表のプロパティの「別名」で相関名を指定する。ACCESSが生成する SQL文では、 表名 AS 相関名 となるが、AS がなくても問題はない。


INNER JOIN文節は、[商品]にしか存在しない[商品番号]"Z01" や "Z11" は、結果として表示されていません。しかし、片方の表にしか存在しない場合でも表示したいことがあります。そのようなときは、LEFT JOIN文節あるいは RIGHT JOIN文節を使用します。

4.2.2 LEFT JOIN

LEFT JOIN文節は、左側の表に存在する行は、右側の表に対応する行がなくても必ず表示されます。そのとき、右側の表の対応する値のない列は NULL となります。

ACCESSの「クエリデザイン」
     
フィールド: 商品番号商品名数量合計: 数量 
テーブル: 商品商品受注明細 
集計: グループ化グループ化合計 
並べ替え:     
表示:     
抽出条件:     
または:     
SELECT 商品番号, 商品名, Sum(数量) AS 数量合計
 FROM 商品 LEFT JOIN 受注明細
   ON 商品.商品番号 = 受注明細.商品番号
 GROUP BY 商品.商品番号, 商品名
    


<表示結果>
商品番号商品名数量
A01テレビ(液晶大型)
5
A11テレビ(液晶小型)
10
G02DVDレコーダ
3
S05ラジオ
3
Z01冷蔵庫
 
Z11エアコン
 

ACCESSでは …
「クエリデザイン」で、上記のようなSQLを作成する場合には、表同士をつないでいる線の結合プロパティを 2('商品'の全レコードを表示する) に変更(線を選んで右クリックし「結合プロパティ」を選択、表示される「結合プロパティ」で 2 を選択)する。


4.2.3 RIGHT JOIN

RIGHT JOIN文節は、右側の表に存在する行は、左側の表に対応する行がなくても必ず表示されます。そのとき、左側の表の対応する値のない列は NULL となります。

ACCESSの「クエリデザイン」
    
フィールド: 顧客名総合計: 受注合計 
テーブル: 顧客受注 
集計: グループ化合計 
並べ替え:    
表示:    
抽出条件:    
または:    
SELECT 顧客名, 受注合計 AS Sum(受注合計) AS 総合計
 FROM 受注 RIGHT JOIN 顧客
   ON 受注.顧客番号 = 顧客.顧客番号
 GROUP BY 顧客名
    


<表示結果>
顧客名総合計
宇宙商事株式会社
\600,000
株式会社冨田貿易
\653,000
広島商店株式会社
 
有限会社吉野物産
\518,000

ACCESSでは …
「クエリデザイン」で、上記のようなSQLを作成する場合には、表同士をつないでいる線の結合プロパティを 3('顧客'の全レコードを表示する) に変更(線を選んで右クリックし「結合プロパティ」を選択、表示される「結合プロパティ」で 3 を選択)する。





例題 10
次の①~④のSQL文を作成し、表示結果とともに答えよ。

[受注]と[顧客]を結合して、2024/04/02に受注した[受注年月日]と[顧客名]と[受注合計]を表示する。
[受注明細]と[商品]を結合して、同一商品ごとの[数量]の合計を求めて、"数量合計"という列名を付け、[商品名]とともに表示する。
[顧客]と[受注明細]と[商品]を結合して、各顧客ごとの[金額]の合計を求めて、"金額合計"という列名を付け、[顧客名]とともに表示する。



4.3 副照会処理(副問合せ処理)

副照会は副問合せともいわれ、ある照会結果を探索条件として、別の表もしくは同一のテーブルの照会を行うことをいいます。つまり、副照会では最初の照会を副として、次の照会(主照会)を行うことです。このためには、SELECT文の中の、IN 述語に続く ( )の中に副照会の SELECT文を指示します。

ACCESSの「クエリデザイン」
   
フィールド: 顧客名顧客番号
テーブル: 顧客顧客
並べ替え:   
表示:   
抽出条件:   In (select 顧客番号 from 受注 where 受注年月日 = #2024/04/02#)
または:   


例えば、「2024年4月2日に受注した[顧客]の[顧客名]を表示する」は、次のようになります。

SELECT 顧客名
  FROM 顧客
 WHERE 顧客番号
    In (select 顧客番号
          from 受注
         where 受注年月日 = #2024/04/02#)
    







 ┌──
 │
 │
 │
 │
 │副照会
 │
 │
 │
 │
 │
 │
 │
 └─→
      
受注
伝票番号受注年月日顧客番号受注合計
000012024/04/011001
\640,000
000022024/04/021006
\518,000
000032024/04/021003
\600,000
000042024/04/051001
\3,000

select 顧客番号 from 受注 where 受注年月日 = #2024/04/02#
              
顧客
顧客番号顧客名住所電話番号
1001株式会社冨田貿易東京都港区芝浦1-X-XX03-3256-XXXX
1003宇宙商事株式会社東京都足立区神明22-XX03-5126-XXXX
1006有限会社吉野物産大阪府大阪市中央区城見23-XX06-6112-XXXX
1010広島商店株式会社広島県広島市中区基町5-XX 
主照会
│SELECT 顧客名 FROM 顧客 WHERE 顧客番号 In ("1003", "1006")
↓
              
<表示結果>
顧客名
宇宙商事株式会社
有限会社吉野物産

また、副照会の結果以外を主照会の条件に使用したい場合には、NOT IN 述語を使用します。

ACCESSの「クエリデザイン」
   
フィールド: 顧客名顧客番号
テーブル: 顧客顧客
並べ替え:   
表示:   
抽出条件:   Not In (select distinct 顧客番号 from 受注)
または:   



例えば、[受注]に記録されていない[顧客]の[顧客名]を表示する」は、次のようになります。

SELECT 顧客名
  FROM 顧客
 WHERE 顧客番号
   Not In (select distinct 顧客番号 from 受注)
    

受注
受注番号受注年月日顧客番号受注合計
000012024/04/011001
\640,000
000022024/04/021006
\518,000
000032024/04/021003
\600,000
000042024/04/051001
\3,000






 ┌──
 │
 │
 │
 │
 │
 │
 │
 │
 │
 │
 └─→
      
│
│副照会
↓select distinct 顧客番号 from 顧客明細表
              
顧客番号
1001
1003
1006

顧客
顧客番号顧客名住所電話番号
1001株式会社冨田貿易東京都港区芝浦1-X-XX03-3256-XXXX
1003宇宙商事株式会社東京都足立区神明22-XX03-5126-XXXX
1006有限会社吉野物産大阪府大阪市中央区城見23-XX06-6112-XXXX
1010広島商店広島県広島市中区基町5-XX 
主照会
│SELECT 顧客名 FROM 顧客 WHERE 顧客番号 Not In ("1001", "1003", "1006")
↓
              
<表示結果>
顧客名
広島商店




例題 11
次の①~③のSQL文を作成し、表示結果とともに答えてください。

1商品につき、200,000以上の発注を最低1回は行っている[商品]の[商品名]を表示する。
[商品番号]"A11" を注文した[顧客]の[顧客名]と[住所]を表示する。
2024年4月2日以外に受注した[商品]の[商品番号]と[数量]を表示する。


4.4 相関副問合せ

相関副問合せは、副問合せを使用して、複数の表を比較して一致するまたは一致しないレコードを検索することをいいます。

ACCESSの「クエリデザイン」
    
フィールド: 商品番号商品名式1: Exists (select * from 受注明細 where
テーブル: 商品商品 
並べ替え:    
表示:    
抽出条件:   True
または:    


例えば、「[受注明細]に存在する[商品番号]と一致する[商品番号]と[商品名]を表示する」には、次のようになります。

SELECT 商品番号, 商品名
  FROM 商品
 WHERE EXISTS (
   select * from 受注明細 
    where 商品.商品番号 = 受注明細.商品番号
   )
  
<表示結果>
商品番号商品名
A01テレビ(液晶大型)
A11テレビ(液晶小型)
G02DVDレコーダ
S05ラジオ

ACCESSでは …
ACCESSでは、EXISTS は、述語(句)ではなく、関数として実現されているため、EXISTS( ... ) の結果を TRUE か FALSE かで判断する必要があり、次のようになる。なお、「式1」という別名が付加されるが、SQLにはその名前は現れない。
SELECT 商品番号, 商品名
  FROM 商品
 WHERE Exists (
   select * from 受注明細 
    where 商品.[商品番号] = 受注明細.[商品番号]
   )=True
また、EXISTS( ... ) = TRUE と Not EXISTS( ... ) = FALSE は同じ意味である。


4.5 ビューの活用

ビューは前述したとおり、データ定義言語によって定義されます。ビューは、実在表の一部分だけを取り出してビューとして定義することもできますし、複数の表を組み合わせてビューとして定義することもできます。ここでは、後者の複数表を組み合わせて作成する方法について説明します。

例えば、結合処理のときに用いた「[顧客]と[受注]を結合して[顧客名]と[受注番号]を取り出す」は、次のように「[顧客名]と[受注番号]からなるビューを作成する」という方法でも定義できます。

CREATE VIEW 顧客受注 
 AS SELECT 顧客名, 受注番号
      FROM 顧客 INNER JOIN 受注 ON 顧客.顧客番号 = 受注.顧客番号

この結果、[顧客]と[受注]を結合したビュー[顧客受注]が定義されます。


ACCESSでは …
ビューではなくクエリと呼んでいます。クエリを作成することによって、実在表の内から条件に合ったデータだけを抽出することができる。
SELECT 顧客名, 受注番号
  FROM 顧客 INNER JOIN 受注 ON 顧客.顧客番号 = 受注.顧客番号
を[顧客受注]という名前でクエリとして保存する。

そして、定義され(保存され)たクエリに対しては、実在表と同様にデータのアクセスが可能であり、この点が使いやすさの向上につながっています。

例えば、「[受注番号]が"00001"の[顧客名]を表示する」は、結合処理のSQL文で指定すると次のようになります。

SELECT 顧客名
  FROM 顧客 INNER JOIN 受注 ON 顧客.顧客番号 = 受注.顧客番号
 WHERE 受注番号 = "00001"    

この例を、先に定義したクエリ[顧客受注]を用いてSQL文で指定すると、次のようになります。

SELECT 顧客名
  FROM 顧客受注
 WHERE 受注番号 = "00001"    

この2つのSQL文を比べると、クエリ(ビュー)を用いたほうが単純です。クエリ(ビュー)を定義しておくと、受注レコードが増えて、実在表である[顧客]や[受注]が更新されれば、自動的に[顧客受注]のデータも更新されます。

このように、複数の表から求めるデータを取り出すとき、あらかじめ求めるデータを含んだクエリ(ビュー)を作成しておき、そのビューからデータを取り出すほうが有用です。


また、簡単な SELECT文ならば、わざわざ別にクエリ(ビュー)として作成しなくても、SELECT文を直接 FROM文節に記述することによって同様な結果を得ることができます。

ただし、FROM文節にSELECT文を直接記述する場合は、かっこで囲む必要があります。

SELECT 顧客名
  FROM (SELECT 顧客名, 受注番号
          FROM 顧客 INNER JOIN 受注 ON 顧客.顧客番号 = 受注.顧客番号)
 WHERE 受注番号 = "00001"    

ACCESSでは …
ACCESSの「クエリデザイン」の「デザイン」ビューでは、テーブル欄に SELECT文を記入できないので、SELECT文を直接 FROM文節に記述することはできない。
ただし、SQLとしては作成できるので、「SQL」ビューで作成する。