2022年8月、ホームページを全面リニューアルしました! 情報を分かりやすくお伝えできるサイト作りを目指してまいります。

SQL入門(SQLを理解する)!

1.リレーショナルデータベースってなに?

 RDB( リレーショナルデータベース)はデータベースの一種である。それではデータベースとは何かと言うと、

■ データを貯めて保存する。
■ 保存されているデータを利用する手段を提供する(例えば、帳票や画面)。

しかも、リレーショナルデータベースは、エクセルのスプレッドシートのようにデータを二次元の表として考える。
表自体はテーブル(Table)と呼ばれ、横1行を行またはレコード(Record)と呼ぶ。同じく縦1列を列またはロウ(Row)、またはカラム(Column)とも呼ぶ。さらに、たて一列の項目名をフィールド(Field)と呼ぶ。
リレーショナルデータベースは、このような表を複数含んだテーブルの集まりである。原則として、一つのデータベースの中では同じ名前のテーブルは許可されない。データベースには、Tree型データベースなどがあるが、やはりリレーショナルデータベースが代表的である。


2.SQLってなに?

SQLは、リレーショナルデータベースを制御操作する言語である。つまり、

■ テーブルを作る。
■ テーブルのトランザクションを行う(読み書き編集)。
■ データベースを保守する。


3.SQL構文集

● 全てのデータを取り出す(抽出)

表の中のすべてのデータを取り出す。

基本書式  SELECT * FROM <テーブル名>;


● 列名を指定してデータを取り出す

基本書式  SELECT <フィード名リスト> FROM <テーブル名>

DEPTという表からDEPTNOという列を指定して、そのデータを取り出す。

実行例  SELECT DEPTNO FROM DEPT;

複数の列を取り出す。複数指定の場合は、列名をカンマ( , )で区切りながら指定する。この例は、DEPTテーブルからDEPTNOとDNAMEという列を取り出す。

実行例  SELECT DEPTNO,DNAME FROM DEPT;


● テーブル名を付加する

テーブルが複数有って同じ名前の列名が存在する場合、テーブル名を付加することが出来る。これは、複数のテーブルがあってその中に同じテーブル名が存在した場合、わかりやすいが故に使う。テーブルが単独の場合は必要ない。

実行例  SELECT DEPT.DEPTNO,DEPT.DNAME FROM DEPT;


● 計算式を使う

計算式を使う。下の例は、EMPテーブルのSAL列の値に2を乗じた値を取り出す。

実行例  SELECT SAL*2 FROM EMP;

列と式を一緒に指定する。

実行例  SELECT SAL*2,SAL FROM EMP;

定数を使う。例は、EMPテーブルから9999という数値とSAL列を取り出す。

実行例  SELECT 9999,SAL FROM EMP;

数値はこの例のようにそのまま書くことができるが、他のデータ型は書くときにクォーテーションなどで囲む。

実行例  SELECT SAL,’もしも給料が上がったら’,SAL*2 FROM EMP;


● 同じフィールド名とエーリアス(別名)

一つのテーブルに同じフィールド名が存在する。

実行例  SELECT SAL,SAL FROM EMP;

フィールド名が同じ場合は、エーリアスを付ける事ができる。以下の例のようにASパラメータに続いてフィールド名を指定すればよい。

実行例  SELECT SAL AS SALARY,SAL AS 給料 FROM EMP;

フィールド名を使う場合は、フィールド名が同じ時ばかりではない。計算式等を用いた場合も使うと便利である。

実行例  SELECT SAL AS 今の給料,SAL+1000 AS 昇級後の給料 FROM EMP;


● 条件を入れて書く(WHEREパラメータ)

問い合わせに条件を付けるには、SELECT文のWHEREの後に条件式を書く。

基本書式  SELECT <フィード名リスト> FROM <テーブル名> WHERE <条件式>;

この例は、商品テーブルから商品コードが10のレコードデータを取り出す。

実行例  SELECT * FROM 商品 WHERE 商品コード = 10;

この例は、商品テーブルから商品コードが10より大きいフィールドデータを取り出す。

実行例  SELECT * FROM 商品 WHERE 商品コード > 10;

他の言語と同様にSQLには比較演算子がある。その種類は次のようなものある。

・<  条件より小さい
・>  条件より大きい
・<= 条件より小さいか同じ
・>= 条件より大きいか同じ
・=  条件と同じ
・<> 条件と異なる

その他に、値が0からnの間、リストされた値のどれかと等しい、文字列型の列に対してある文字を含んでいるなどの指定ができる。以下の例を参照。

・BETWEEN <A> AND <B>  条件Aと条件Bの間
・IN                    条件の何れかと一致
・LIKE                  条件を含む

この例は、商品テーブルから単価が1000円台のフィールドデータを取り出す。

実行例  SELECT * FROM 商品 WHERE 単価 BETWEEN 1000 AND 1999;

この例は、商品テーブルから商品コードがカッコの中の値のどれかと一致するフィールドデータを取り出す。

実行例  SELECT * FROM 商品 WHERE 商品コード IN (10,20,30,40);

この例は、商品テーブルから商品名に100%という文字列を含むフィールドデータを取り出す。

実行例  SELECT * FROM 商品 WHERE 商品名 LIKE ‘*100%’;

NOTは、「その条件に一致しない」という意味になる。たとえば、この例はカッコの中の値以外の商品コードのフィールドデータを取り出す。

実行例  SELECT * FROM 商品 WHERE 商品コード NOT IN (10,20,30,40);

間違いやすいのは、値が入っていない状態である。これは0や空白文字(いわゆるスペース)が入っているのとも違う。まったく何も入っていない状態で、これをNULL(ヌルとかナル)と呼ぶ。あるフィールドデータがNULLであるとかないとかいう問い合わせはデータベースの検索ではよく行う。あるフィールドデータがNULLかどうかを見るには、IS演算子を使わなくてはならない。この例は、得意先テーブルでファクシミリの値がNULLのものを取り出す。

実行例  SELECT * FROM 得意先 WHERE ファクシミリ IS NULL;

NOTを合わせれば、「NULLではない」という条件式を作ることが出来る。この例は、得意先テーブルでファクシミリの値がある(NULLではない)フィールドデータを取り出す。

実行例  SELECT * FROM 得意先 WHERE ファクシミリ IS NOT NULL;

論理演算子についてはAかつB(AND条件)とか、AまたはB(OR条件)などである。この例は、商品テーブルで区分コードが1でなおかつ商品名が果汁で始まるフィールドデータを取り出す。

実行例  SELECT * FROM 商品 WHERE 区分コード = 1 AND 商品名 LIKE ‘果汁*’;

この例は、商品フィールドで商品コードが1または2のフィールドデータを取り出す。

実行例  SELECT * FROM 商品 WHERE 商品コード = 1 OR 商品コード = 2;

条件が3個以上あってなおかつANDとORが入り組んでいる場合は、条件が意図したものと違って解釈されないようカッコをつけるようにする。この例は商品テーブルで区分コードが1でなおかつ商品名が果汁で始まるフィールドデータもしくは商品コードが8のフィールドデータを取り出す。この場合、カッコはあってもなくても同じだが有った方がわかりやすい。

実行例  SELECT * FROM 商品 WHERE (区分コード = 1 AND 商品名 LIKE ‘果汁*’) OR (商品コード = 8);

以下の■の2つ条件式は同じ意味である。条件式の書き方は何通りか有るが、この場合はINを使った式の方が良さそうである。

■ 実行例  SELECT * FROM 商品 WHERE 商品コード IN (10,20,30);

■ 実行例  SELECT * FROM 商品 WHERE 商品コード = 10 OR 商品コード = 20 OR 商品コード = 30;


● SQL集合関数ってなに?

あるテーブルのあるフィールドデータで一番大きいもしくは小さい値を問い合わせたい。さらには、平均値を求めたい。そういった処理を行うSQL関数である。DBによっても違うと思うが、一般的に以下の計算をする関数は標準的に含まれる。 他には標準偏差や分散を求めるSQL関数もある。

・レコードの数を求める。
・あるフィールドデータの最大・最小値を求める。
・あるフィールドデータの値の合計を求める。
・あるフィールドデータの平均値を求める。

関数  COUNT (<式>)

選択されたレコードの数を求める。以下の基本書式で、あるテーブルに含まれるレコードの内とカッコ内の式もしくはフィールド名がNULLでないレコードの数を数える。ただし、NULLを含めてすべてのレコードを数える場合は、カッコにアスタリスク(*)を付ける。

基本書式  SELECT COUNT(<フィールド名>) FROM <テーブル名>;

基本書式  SELECT COUNT(*) FROM <フィールド名>;

この例は、得意先テーブルからファクシミリの値がNULLでない件数を取り出す。

実行例  SELECT COUNT(ファクシミリ) FROM 得意先;

この例は、社員テーブルにあるすべての社員の人数を取り出す。

実行例  SELECT COUNT(*) FROM 社員;

関数  MAX(<式>);

カッコ内の式(フィールド名)の最大値を求める。

基本書式  SELECT MAX(<フィールド名>) FROM <テーブル名>;

この例は、社員テーブルから社員の誕生日の最大値を求める。

実行例  SELECT MAX(誕生日) FROM 社員;

関数  MIN(<式>)

カッコ内の式(フィールド名)の最小値を求める。

基本書式  SELECT MIN(<フィールド名>) FROM <テーブル名>;

この例は、社員テーブルから社員コードの最小値を求める。

実行例  SELECT MIN(社員コード) FROM 社員;

関数  AVG(<式>);

カッコ内の式(フィールド名)の平均値を求める。

基本書式  SELECT AVG(<フィールド名>) FROM <テーブル名>;

この例は、商品テーブルから単価の平均値を求める。

実行例  SELECT AVG(単価) FROM 商品;

関数  SUM(<式>)

カッコ内の式(フィールド名)の合計値を求める。

基本書式  SELECT SUM(<フィールド名>) FROM <テーブル名>;

この例は、受注テーブルから運送料の合計値を求める。

実行例  SELECT SUM(運送料) FROM 受注;

この書式は、最大値を求める場合、テーブルの中で条件式に合うレコードの中での最大値を求める。

基本書式  SELECT MAX (<フィールド名>) FROM <テーブル名> WHERE <条件式>;

さらに、この書式はASバラメータを付けてエーリアスで取り出す。

基本書式  SELECT COUNT (*) AS <フィールド名(エーリアス)> FROM <テーブル名>;


● 条件別にまとめて扱う(GROUP BY:グループ化する)

GROUP BYパラメータは、あるテーブルのレコードを条件ごとにまとめて扱うものである。たとえば人事関係の表なら部ごとの給与の平均を取るとか。 一般的にGROUP BYパラメータはSELECTコマンドのオプションとして使われる。

基本書式  SELECT <SQL集合関数> FROM <テーブル名> GROUP BY <フィールド名>;

この例は、社員テーブルから各部の人数(=レコード数)を取り出す。

実行例  SELECT COUNT (*) AS 人数 FROM 社員テーブル GROUP BY 部コード;

この例は、人数だけでなく部コードも一緒に取り出す。

実行例  SELECT 部コード,COUNT(*) AS 人数 FROM 社員テーブル GROUP BY 部コード;

SQL集合関数を使う場合、集合関数の他に問い合わせで指定できるものはGROUP BYパラメータに使ったフィールドデータのみである。したがって、次のSELECTコマンドの氏名はGROUP BYパラメータに出でこないのでエラーとなる。

エラー例  SELECT 氏名,部コード,COUNT(*) AS 人数 FROM 社員テーブル GROUP BY 部コード;

GROUP BYでグループ化する基準となるフィールドは複数ある。その時はカンマ( , )で区切って指定すること。以下、実行例参照。

実行例  SELECT 部コード,課コード,COUNT(*) AS 人数 社員テーブル GROUP BY 部コード,課コード;

課は部に含まれる。複数のフィールドデータでグループ化するなら、グループ化に用いるフィールドデータには親子関係がある。より大きな範囲のフィールド名を左に、小さいフィールド名は右に書くようにする。間違うとアバウトな結果が表示されてしまうので注意すること。
テーブル全体がグループ化の対象でない場合は、WHEREパラメータと一緒に使うこと。さらに、GROUP BYパラメータはWHEREパラメータの後ろに書く。この例は、部コードが11以上の部の人数を求める。

実行例  SELECT COUNT(*) AS 人数 FROM 社員テーブル WHERE 部コード > 10 GROUP BY 部コード;

WHEREパラメータは通常グループ化する前に条件をつける。
たとえば前述の例で言うと部コードが11以上の部の人数を求めた。これがもし仮に、人数が10人より多い部の人数を部ごとに求めるとしたらSQL集合関数を使った後に条件が必要になる。しかし、それではWHEREパラメータは使うことが出来ない。HAVINGパラメータはこのようなときに使う。
また、HAVINGパラメータはWHEREパラメータやGROUP BYパラメータの後に記述する。

実行例  SELECT COUNT(*) AS 人数 FROM 社員テーブル WHERE 部コード > 10 GROUP BY 部コード HAVING COUNT(*) >= 10;


● 並べ替えのための昇・降順指定(ORDER BY)

並べ替えって、あるフィールドデータの値の大小を比較して小さい順または大きい順に表示する事である。何のフィールドデータを並べ替えの基準にするして昇順か降順かを指定するにはORDER BYパラメータを使う。ORDER BYパラメータにはフィールド名もしくはフィールドデータを使った式を指定する。
注) 並べ替えにおいて降順指定場合は、 「 DESC 」と言う予約語を付ける。昇順の場合は必要なし。

基本書式  SELECT <列名リスト> FROM <テーブル名> ORDER BY <フィールド名> [DESC];

この例は、EMPテーブルの内容を取り出してEMPNOの昇順で表示する。

実行例  SELECT * FROM EMP ORDER BY EMPNO;

この例は、EMPテーブルの内容を取り出してEMPNOの降順に表示する。

実行例  SELECT * FROM EMP ORDER BY EMPNO DESC;

並べ替えの基準となる列が複数である事も珍しくない。たとえば人事関係の表なら、部、課、班で並べ替えたりもする。基準となる列名をカンマ( , )で区切って設定する。

基本書式  SELECT <フィールド名リスト> FROM <テーブル名> ORDER BY <フィールド名1> [ ,<フィールド名2> [ ,・・・] ] [ DESC ];

基準となるフィールド名の記述は、より大きいキーを左に指定する。前述の例でいくと、部は課より大きいので左に書くと言うことになる。
この例は、EMPテーブルの内容をDEPTNOとEMPNOで並べ替える。

実行例  SELECT * FROM EMP ORDER BY DEPTNO,EMPNO;

この例は、EMPテーブルでJOBがANALYSTのレコードを取り出して、さらにそのレコードのSALフィールドを小さい順に並べ替えている。

実行例  SELECT * FROM EMP WHERE JOB = ‘ANALYST’ ORDER BY SAL;


● レコードを追加する(INSERT INTO)

レコードを追加(新規書き込み)するにはINSERT INTOコマンドを使う。
INSERT INTOコマンドには、テーブルに1レコードずつ追加する場合と一度に0~nレコードまとめて追加する場合があり、ここでは前者を先に説明する。また、追加は一度に1個のテーブルが対象となる。テーブルに1行ずつ追加する時は、設定する値を書くためにVALUESパラメータを使う。書式は、下記参照。

基本書式  INSERT INTO <テーブル名> (<フィールド名リスト>) VALUES (<値のリスト>);

この例は、EMPテーブルに1レコード追加する。

実行例  INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO) VALUES (9211, ‘YAMADA’, ‘SE’, 7900, ’92-04-01′, 1000, 10);

VALUESを挟んで、カッコが二つあり左のカッコには値を設定するフィールド名をリストし右のカッコにはそこに入れる値をリストする。
値のリストを記述するときに、気を付ける事がいくつかある。フィールド名の並びは自由であるがフィールド名の順に値のリストも並べること。それから、文字列型や日付/時刻型のフィールドに代入する値はシングルクォーテーション( ’)で囲むこと。値を囲む文字は、データベースの種類やデータ型の種類によってまるっきり違う場合が有るのでマニュアルを参照すること。
ちなみに、日付・時刻型の値に対してはシャープ( # )で囲む。

実行例  INSERT INTO 社員 (社員コード, フリガナ, 氏名, 入社日) VALUES (999, ‘ヤマダ’, ‘山田’, #92/04/01#);


● 複数のレコードを追加する

どういう意味かというと、あるテーブルから選択したレコードを別のテーブルに書き込む。すべてのフィールドとすべてのレコードをコピーする場合も有れば一部だけの場合もあり。

基本書式  INSERT INTO <テーブル1> SELECT * FROM <テーブル2>;

これを実行するとテーブル2の内容がテーブル1に丸ごと複写される。
SELECT文にWHEREパラメータが付く事もありテーブル2を部分的にコピーする。テーブル2のレコードとテーブル1のレコードでキーとなる列に重複する値があるとエラーが発生する。このようにテーブルからテーブルへすべての列を複写するばかりではなく部分的に複写する場合もある。


● データを更新する(UPDATE)

データを更新する場合は、UPDATEコマンドを使う。更新の基本書式は以下を参照。必ずSETパラメータと一緒に使うこと。

基本書式  UPDATE <テーブル名> SET <代入式のリスト>;

SET以降の代入式は、「フィールド名 = 値」という形で記述する。
この例は、商品テーブルの単価のフィールドを1.1倍してる。

実行例  UPDATE 商品 SET 単価 = 単価 * 1.1;

代入する値は、何も数式出なくても良い。定数の場合もある。

実行例  UPDATE 商品 SET 単価 = 100;

WHEREパラメータを省略すると、テーブルの全てのレコードが変更される。更新したいフィールドが複数ある場合は、カンマ( , )で区切って指定する。
この例は、商品テーブルの単価を1.1倍して在庫を0にしている。

実行例  UPDATE 商品 SET 単価 = 単価 * 1.1, 在庫 = 0;

更新の対象は0~nレコードである。
WHEREパラメータを使って更新するレコードを限定して行う場合が多いが何も条件を指定しなければテーブル全体が更新されることになる。また、条件式を付けるなら後付けになる。

実行例  UPDATE 商品 SET 単価 = 単価 * 1.1, 在庫 = 0 WHERE 区分コード = 2;


● レコードを削除する(DELETE)

レコードを削除する場合は、DELETEコマンドを使う。その他にテーブルそのものを削除する方法があるがフィールドの削除はない。

基本書式  DELETE FROM <テーブル名>;

この例は、EMPテーブルのレコードをすべて削除する。
削除された後は、0レコードのテーブルが残る。テーブルの定義そのものは削除されないので勘違いしないこと。

実行例  DELETE FROM EMP;

しかし、上の実行例のようにレコード全部を削除する事は殆どない。だいたいがWHEREパラメータを付けて、特定のレコードを削除するする場合が多い。
この例は、EMPNOが9211のレコードを削除してみる。もし仮に条件にあてはまる行がなければ何も削除されずエラーにもならない。

実行例  DELETE FROM EMP WHERE EMPNO = 9211;

この例は、社員テーブルからフリガナが’ヤマダ’のレコードを削除する。

実行例  DELETE * FROM 社員 WHERE フリガナ = ‘ヤマダ’;


● テーブルの作成とテーブルの削除(CREATE TABLE & DROP)

テーブルを作成する場合は、CREATE TABLEコマンドを使う。コマンドの後にテーブル名・フィールド名やデータ型を記述していく。複数のテーブルが必要な場合は、面倒なので拡張子がsqlと言うファイルを作りエディタでテーブル定義をしてデータベースに登録すると便利だ。
データ型の定義方法は、データベースの種類によって違うで注意して欲しい。

書式  CREATE TABLE <テーブル名> (<フィールド名とデータ型のリスト>);

テーブル定義を削除する場合は、DROPコマンドを使う。また、DROPコマンドで他に削除できるものはキーやインデックスがある。
また、余談だがSQLにはテーブルの構造を変更するALTERというコマンドがある。

書式  DROP <テーブル名>;

以上

コメント