データベースマネジメント:SQL(最終更新:2015/12/06 16:34:41 JST)
SELECT文の高度な利用法として副問合せ(sub query)と呼ばれる手法がある.SELECT文の中にSELECT文を埋め込むことで複雑な条件設定を行う手法である.副問合せは,SELECT句の出力するフィールド名,FROM句,WHERE句のそれぞれで使用することができる.また副問合せは,副問合せのSELECT文に外側のテーブルを含まない副問合と外側のテーブルを含む相関副問合せに分けることができる.
WHERE句で使用して,副問合せのSELECT文で抽出されたレコードに一致するレコードを外側のSELECTで抽出する処理である.IN句,NOT IN句,比較演算子が利用できる.ただし比較演算を用いた場合は副問合せの結果が単独の値となるようにすべきである(予期せぬ結果となる).
/* 副問合せ: INの書式 テーブル2のフィールド1のうち条件を満たすレコードを抽出し, それらと一致するテーブル1のフィールド1のレコードを含むものを抽出 */ SELECT フィールドのならび FROM テーブル1 WHERE フィールド1 IN (SELECT フィールド1 FROM テーブル2 WHERE 条件)
/* 副問合せ:NOT INの書式 テーブル2のフィールド1のうち条件を満たすレコードを抽出し, それらと一致するテーブル1のフィールド1のレコードを含まないものを抽出 */ SELECT フィールドのならび FROM テーブル1 WHERE フィールド1 NOT IN (SELECT フィールド1 FROM テーブル2 WHERE 条件)
/* 副問合せ:比較演算子(例えば「=」) テーブル2のフィールド1のうち条件を満たす単独のレコードを抽出し, その値と一致するテーブル1のフィールド1のレコードを含むものを抽出 */ SELECT フィールドのならび FROM テーブル1 WHERE フィールド1 = (SELECT フィールド1 FROM テーブル2 WHERE 条件)
副問合せを比較演算子で用いるときに,複数のレコードが副問合せで抽出された場合,最初のレコードが用いられる(少なくともSQLiteでは).混乱を避けるためにも単独の値となるように条件を設定すべきである.
教科書には起債されていないが,フィールドのならび,FROM句に対しても使用できる.フィールドのならびに使用する際は必ず単独の値となること必要である.
/* 副問合せ:フィールドのならびへの使用 [注文]テーブルから<商品コード>ごとの数量と「数量の総数」のフィールドを出力 */ SELECT 商品コード, SUM(数量), (SELECT SUM(数量) FROM 注文) FROM 注文 GROUP BY 商品コード
FROM句へ使用した場合は,抽出元となるテーブルを副問合せの条件で先に抽出して制限することになる.この場合は別名を利用する.
/* 副問合せ:FROM句への使用 [注文2]テーブルの<数量>フィールドが10以上のレコードのうち, [商品]テーブルの<商品コード>が同じレコードを抽出 */ SELECT C2.日付, 商品名, 単価, C2.数量 FROM (SELECT * FROM 注文2 where 数量>=10) as C2, 商品 where C2.商品コード=商品.商品コード
副問合せの条件の中に外側の主問合せのフィールドを利用するものを相関副問合せと呼ぶ.EXISTS句あるいはNOT EXISTS句を用いる.相関副問合せでは,まず外側の主問合せの表の1行目が内側の副問合せに渡される.そして副問合せが実行される.EXISTS句の場合は,副問合せでレコードが抽出された場合,それと一致する外側の表のレコードを出力し,副問合せで抽出されない場合は無視する.
SELECT 日付, 商品コード, 数量 FROM 注文2 WHERE EXISTS (SELECT * FROM 商品 WHERE 単価>=300 AND 注文2.商品コード=商品.商品コード) /* 注文2の1レコードずつ,単価300以上かつ商品コード一致の成立を判断 */
NOT EXISTS句の場合は,逆に抽出されなかった場合,それと一致する外側の表のレコードを出力し,副問合せで抽出された場合は無視する.
SELECT 日付, 商品コード, 数量 FROM 注文2 WHERE NOT EXISTS (SELECT * FROM 商品 WHERE 単価>=300 AND 注文2.商品コード=商品.商品コード) /* 注文2の1レコードずつ,単価300以上かつ商品コード一致の不成立を判断 */
データベースでは作成したテーブルに対して,データの追加,更新,削除の操作を行う必要がある.これらの操作を実現するためのSQL文を取り上げる.
テーブルにレコードを追加するためにはINSERT文を用いる.
1件のレコードを追加するためには,INSERT INTO~ VALUES~文を用いる.INTO句の後にテーブル名とフィールド名を指定し,VALUES句の後に追加するレコードを記述する.
INSERT INTO 商品(商品コード, 商品名, 単価) VALUES(201, 'ごませんべい', 350) /* [商品]テーブルに「201,ごませんべい,350」のレコードが追加される.*/
なお,追加するレコードのフィールド名の並びがテーブルと一致している場合には,テーブル名の後ろのフィールド名は省略可能である.ただし,フィールド名の並び順が異なる場合や一部のフィールドにのみデータを追加する場合は省略不可である.
別のテーブルから選択したレコードをまとめて追加するためには,INSERT INTO~ SELECT~文を用いる.SELECT句の後ろに追加するフィールド名を通常のSELECT文の文法に従い記述する.
INSERT INTO 在庫商品(商品コード, 商品名, 単価) SELECT 商品コード, 商品名, 単価 FROM 商品 WHERE 単価>=300 /* [商品]テーブルの<単価>が300以上のレコードが[在庫商品]テーブルに追加される. もちろん[在庫商品]と[商品]テーブルがなければいけない.*/
テーブルのレコードの数値または文字列を置き換える(更新する)ためには,UPDATE文を用いる.UPDATE文では更新後のレコードの値をSET句の後に指定し,更新したいレコードの条件をWHERE句の後ろに指定する.
UPDATE 商品 SET 商品名='あられせんべい' WHERE 商品コード=102 /* <商品コード>が102のレコードの<商品名>を「あられせんべい」に変更する.*/
「WHERE 商品名='あられ'」であれば<商品名>に複数の「あられ」があれば,すべて更新される.場合によって使い分けが必要.
テーブルからレコードを削除するためには,DELETE文を用いる.対象となるテーブル名をFROM句の後に指定し,削除するレコードの条件をWHERE句の後に記述する.
DELETE FROM 商品 WHERE 商品名='ポテトチップス' /* <商品名>が「ポテトチップス」であるレコードを削除.*/
特定のレコードを削除するためには,条件として主キーを指定すると事故が起こらない.
このサイトに関するお問い合わせは,連絡先のページをご覧ください.