Windows+Apache+PHP+MySQL(5.0)によるWebアプリケーション

第4章 MySQLによるWebアプリケーションの基礎



4.7 レコードの追加

■テーブルへのデータの入力

 テーブルへデータを入力するには、テーブルにレコードを順次追加する操作になります。レコードの追加には「INSERT INTO」文を使います。1回に1レコードのみ追加できます。

INSERT INTO テーブル名
        (フィールド名1,フィールド名2,・・・,フィールド名n)
 VALUES  (値1     ,値2     ,・・・,値n);

 最初のかっこ「(・・・)」の中に、レコードの中のデータを入力するフィールド名を[,」(半角カンマ)で区切って記入します。VALUES句のあとの「(・・・)」の中に、各フィールドに入力するデータを前のかっこに記入した順番と同じ順番で記入します。つまり、フィールド名1には値1が入力され、フィールド名2には値2が順次入力されます。テーブルのすべてのフィールドにデータを入力するときは、テーブル名の直後のかっこおよびフィールド名の記述は省略できます。ただし、値の記入順は、テーブルを作成したときのフィールドの記入順にあわせる必要があります。

 また、値の記入位置には、変数を使うことも可能です。なお、値として直接文字列を記入する場合は、文字列を「'」(シングルクォーテーション)あるいは「"」(ダブルクォーテーション)で囲む必要があります。「"」(ダブルクォーテーション)で囲んだ場合は、文字列中にエスケープ記号などの特殊記号があると再評価されるので、注意が必要です。

 サンプルファイル「insert.php」を以下に示します。

 サンプルファイル「insert.php」を以下に示します。

「insert.php」

<?php
// インクルードファイルの読み込み
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>include.php</title>
</head>
<body>
<?php

 // データベースサーバへの接続
 $db = mysql_connect('localhost','webapl','pass1234');

 // データベース名
 $db_name = 'db_hanbai_kanri';

 // データベースの選択
 mysql_select_db($db_name,$db);

 // レコードを追加するテーブル
 $tbl_name = "tbl_shouhin_hyou";

 // テーブルの中の全レコード一覧表示
 show_records($db_name,$tbl_name,$db);
 print "<br>\n";

 // レコード追加のSQL文の作成
 $str_sql = "INSERT INTO {$tbl_name} "
      . "(shouhin_code,shouhin_mei ,tanka)"
      . " VALUES "
      . "('2001' ,'ランチ',800);";


 
// SQL文の実行
 mysql_query($str_sql,$db);

 
// SQL文の表示
 print "\"{$str_sql}\"<br>\n";

 // テーブルの中の全レコード一覧再表示
 show_records($db_name,$tbl_name,$db);

 // データベースサーバの切断
 mysql_close($db);

?>
</body>
</html>

(注)Webアプリケーションの場合は、「SET NAMES」は実行しなくても、文字化けおきないようです。

 結果は、たとえば以下のように表示されます。

 

4.8 レコードの修正

■テーブルのデータの修正

 テーブルのデータを修正(更新)するには、SQLコマンドの「UPDATE」文を使います。

UPDATE テーブル名
 SET   フィールド名1= 値1,フィールド名2 = 値2,・・・,フィールド名n = 値n
 WHERE 更新条件;

 SET句で更新するフィールド名と更新後の値を「=」で結んで記述します。複数のフィールドを同時に更新する場合は、「,」(カンマ)で区切ります。すべてのレコードでなく条件にあったレコードのも更新する場合は、更新条件をWHERE句に記述します。

 サンプルファイル「update.php」を以下に示します。

「update.php」

<?php
// インクルードファイルの読み込み
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>update.php</title>
</head>
<body>
<?php

 // データベースサーバへの接続
 $db = mysql_connect('localhost','webapl','pass1234');

 // データベース名
 $db_name = 'db_hanbai_kanri';

 // データベースの選択
 mysql_select_db($db_name,$db);

 // レコードを更新するテーブル
 $tbl_name = "tbl_shouhin_hyou";

 // テーブルの中の全レコード一覧表示
 show_records($db_name,$tbl_name,$db);
 print "<br>\n";

 // レコード更新のSQL文の作成
 $str_sql = "UPDATE {$tbl_name} "
       . " SET shouhin_mei= '地方御膳',tanka = 900"
       . " WHERE shouhin_code = '1001';";


 // SQL文の実行
 mysql_query($str_sql,$db);
 
 // SQL文の表示
 print "\"{$str_sql}\"<br>\n";

 // テーブルの中の全レコード一覧再表示
 show_records($db_name,$tbl_name,$db);

 // データベースサーバの切断
 mysql_close($db);

?>
</body>
</html>

 結果は、たとえば以下のように表示されます。

 

4.9 レコードの削除

■テーブルのデータの削除

 テーブルのデータを削除するには、SQLコマンドの「DELETE」文を使い該当するレコードを削除します。

DELETE FROM テーブル名
 WHERE 削除条件;

 ただ、このDELETE文は慎重に使う必要があります。一旦データを削除すると元へ戻らなくなります。条件式は慎重に確認しましょう。

 サンプルファイル「delete.php」を以下に示します。

「update.php」

<?php
// インクルードファイルの読み込み
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>update.php</title>
</head>
<body>
<?php

 // データベースサーバへの接続
 $db = mysql_connect('localhost','webapl','pass1234');

 // データベース名
 $db_name = 'db_hanbai_kanri';

 // データベースの選択
 mysql_select_db($db_name,$db);

 // レコードを削除するテーブル
 $tbl_name = "tbl_shouhin_hyou";

 // テーブルの中の全レコード一覧表示
 show_records($db_name,$tbl_name,$db);
 print "<br>\n";

 // テスト用レコードの追加
 $str_sql = "INSERT INTO {$tbl_name}"
      . " (shouhin_code,shouhin_mei ,tanka)"
      . " VALUES "
      . " ('9999' ,'パスタ',1100);";

 // SQL文の実行
 mysql_query($str_sql,$db);

 // テーブルの中の全レコード一覧表示
 show_records($db_name,$tbl_name,$db);
 print "<br>\n";

 // レコード削除のSQL文の作成
 $str_sql = "DELETE {$tbl_name} "
      . " WHERE shouhin_code= '9999';";


 // SQL文の実行
 mysql_query($str_sql,$db);
 
 // SQL文の表示
 print "\"{$str_sql}\"<br>\n";

 // テーブルの中の全レコード一覧再表示
 show_records($db_name,$tbl_name,$db);

 // データベースサーバの切断
 mysql_close($db);

?>
</body>
</html>

 結果は、たとえば以下のように表示されます。

 

4.10 レコードの並べ替え

■テーブルのレコードの並べ替え(ソート)

 あるフィールドの値に注目してレコードの表示順の並べ替え(ソート)を行うにはSQL文の「SELECT」文でORDER句を使います。

SELECT * FROM テーブル名
  ORDER BY  フィールド名

 ORDER BYの後のフィールド名の値にしたがって昇順(辞書順あるいは小さい方から大きい方へ)に並べ替えます。

 並べ替えを降順(辞書の逆順あるいは大きい方から小さい方へ)に並べ替えるときは、フィールド名の後に半角スペースをはさんで、「DESC]をオプションで記述します。

SELECT * FROM テーブル名
  ORDER BY  フィールド名 DESC

 サンプルファイル「order.php」を以下に示します。

<?php
// インクルードファイルの読み込み
include "common.php";
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>order.php</title>
</head>
<body>
<?php

 // データベースサーバへの接続
 $db = mysql_connect('localhost','webapl','pass1234');

 // データベース名
 $db_name = 'db_hanbai_kanri';

 // データベースの選択
 mysql_select_db($db_name,$db);

 // レコードを並べ替えるテーブル
 $tbl_name = "tbl_shouhin_hyou2";

 // テーブルの中の全レコード一覧表示
 show_records($db_name,$tbl_name,$db);
 print "<br>\n";

 // レコードの並べ替え
 $str_sql = "SELECT * FROM {$tbl_name}"
       . " ORDER BY tanka;";

 
// SQL文の実行
 $rs = mysql_query($str_sql,$db);

 
// SQL文の表示
 print "\"{$str_sql}\"<br>\n";

 // 結果セットの中の全レコード一覧表示
 show_rs($rs,$db);
 print "<br>\n";

 // レコードの逆順での並べ替え
 $str_sql = "SELECT * FROM {$tbl_name}"
       . " ORDER BY tanka DESC;";

 
// SQL文の実行
 $rs = mysql_query($str_sql,$db);

 
// SQL文の表示
 print "\"{$str_sql}\"<br>\n";

 // 結果セットの中の全レコード一覧表示
 show_rs($rs,$db);

 // データベースサーバの切断
 mysql_close($db)

?>
</body>
</html>

 結果は、たとえば以下のように表示されます。

 

■複数のフィールドでの並べ替え

 複数のフィールドに着目した並べ替えもできます。その場合は、ORDER BY句の後に並べ替えの優先度の高い順に「,」(半角カンマ)で区切ってフィールド名を記述します。

SELECT * FROM テーブル名
  ORDER BY  フィールド名1,フィールド名2,・・・,フィールド名n

 最初にフィールド名1の値の順にしたがって並べ替えられ、フィールド名1の値が同じレコードが複数あった場合は次にフィールド名2の値にしたがって並べ替えられます。

 たとえば、学生の名簿をまず学部別に並べ替え、次に同じ学部内の学科別に並べ替えそして同じ学科内の学籍番号順に並べ替えるようなときに使います。

 

4.11 あいまい検索

■LIKE演算子とワイルドカード文字「%」

 WHERE句で、文字列の部分一致条件を使う場合は、LIKE演算子とワイルドカード文字「%」(半角)を使います。ワイルドカード文字「%」は0文字以上の任意の文字列を意味します。

 末尾が「定食」となる商品名を含むいわゆる後方一致検索の場合は、「LIKE '%定食」のようにします'。

WHERE フィールド名 LIKE '%文字列'

 前方一致検索の場合は、「LIKE '山%'」のようにします。

WHERE フィールド名 LIKE '文字列%'

 部分一致検索の場合は、「LIKE '%幸%'」のようにします。

WHERE フィールド名 LIKE '%文字列%'

 文字列に変数「$str」を使う場合は、変数を示す特殊文字「$」を再評価する必要があるので、「'」(シングルクォーテーション)の代わりに「"」(ダブルクォーテーション)で囲みます。変数は「{ }」で囲みます。

WHERE フィールド名 LIKE "'%{$str}%"

 サンプルファイル「like.php」を以下に示します。

「like.php」

<?php
// インクルードファイルの読み込み
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>like.php</title>
</head>
<body>
<?php

 // データベースサーバへの接続・データベースの選択
 $db = mysql_connect('localhost','webapl','pass1234');
 $db_name = 'db_hanbai_kanri';
 mysql_select_db($db_name,$db);

 // 検索対象テーブル
 $tbl_name = "tbl_shouhin_hyou3";
 show_records($db_name,$tbl_name,$db);
 print "<br>\n";

 // あいまい検索(LIKE演算子)
 // 後方一致検索
 $str_sql = "SELECT * FROM {$tbl_name} "
       . " WHERE shouhin_mei LIKE '%定食';";

 
// SQL文の実行
 $rs = mysql_query($str_sql,$db);

 // 結果セットの中の全レコード一覧表示
 print "\"{$str_sql}\"<br>\n";
 show_rs($rs,$db);
 print "<br>\n";

 // 前方一致検索
 $str_sql = "SELECT * FROM {$tbl_name} "
       . " WHERE shouhin_mei LIKE '山%';";


 // SQL文の実行
 $rs = mysql_query($str_sql,$db);

 // 結果セットの中の全レコード一覧表示
 print "\"{$str_sql}\"<br>\n";
 show_rs($rs,$db);
 print "<br>\n";

 // 部分一致検索
 $str = '幸';
 $str_sql = "SELECT * FROM {$tbl_name} "
       . " WHERE shouhin_mei LIKE '%{$str}%';";

 // SQL文の実行
 $rs = mysql_query($str_sql,$db);

 // 結果セットの中の全レコード一覧表示
 print "\"{$str_sql}\"<br>\n";
 show_rs($rs,$db);
 print "<br>\n";

 // データベースサーバの切断
 mysql_close($db);

?>
</body>
</html>

 結果は、たとえば以下のように表示されます。

 

■LIKE演算子とワイルドカード文字「_」

 WHERE句で、特定の長さの文字列に一致する条件を指定する場合は、ワイルドカード文字「_」(半角のアンダーバー)を使います。冒頭が「鶴亀」で4文字の商品名を含むレコードを参照する場合は、「LIKE '鶴亀_ _'」とします。(「_ _」は2個連続した半角のアンダーバーの意味です。ここでは分かりやすいように、間に半角スペースを挿入していますが、SQL文では、半角スペースは入れません)。

WHERE フィールド名 LIKE '文字列_ _'

■IN演算子

 WHERE句で、いくつかの特定の値に一致する場合の条件式には、IN演算子を使います。「1000」あるいは「1500」のいずれかに一致する場合という条件式は、「IN(1000,1500)」と記述します。

WHERE フィールド名 IN (候補値1, 候補値2,・・・,候補値n)

■BETWEEN演算子

 下限値から上限値までの間の任意の値に一致する条件式は、BETWEEN演算子を使います。

WHERE フィールド名 BETWEEN 下限値 AND 上限値

 

 以上のサンプルファイル「between.php」を以下に示します。

<?php
// インクルードファイルの読み込み
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>like.php</title>
</head>
<body>
<?php

 // データベースサーバへの接続・データベースの選択
 $db = mysql_connect('localhost','webapl','pass1234');
 $db_name = 'db_hanbai_kanri';
 mysql_select_db($db_name,$db);

 // 検索対象テーブル
 $tbl_name = "tbl_shouhin_hyou3";
 show_records($db_name,$tbl_name,$db);
 print "<br>\n";

 // あいまい検索(LIKE演算子)
 // 文字列長を指定したい場合
 // (鶴亀の後に任意の2文字を含む4文字の文字列を検索する例)
 $str_sql = "SELECT * FROM {$tbl_name} "
       . " WHERE shouhin_mei LIKE '鶴亀__';";

 
// SQL文の実行
 $rs1 = mysql_query($str_sql,$db);

 // 結果セットの中の全レコード一覧表示
 print "\"{$str_sql}\"<br>\n";
 show_rs($rs1,$db);
 print "<br>\n";

 // IN演算子
 $str_sql = "SELECT * FROM {$tbl_name} "
       . " WHERE tanka IN(1000,1500);";


 // SQL文の実行
 $rs2 = mysql_query($str_sql,$db);

 // 結果セットの中の全レコード一覧表示
 print "\"{$str_sql}\"<br>\n";
 show_rs($rs2,$db);
 print "<br>\n";

 // BETWEEN演算子
 $str_sql = "SELECT * FROM {$tbl_name} "
       . " WHEREtankaBETWEEN 2000 AND 3000;";


 // SQL文の実行
 $rs3 = mysql_query($str_sql,$db);

 // 結果セットの中の全レコード一覧表示
 print "\"{$str_sql}\"<br>\n";
 show_rs($rs3,$db);
 print "<br>\n";

 // 結果セット(結果ID)の開放
 mysql_free_result($rs1);
 mysql_free_result($rs2);
 mysql_free_result($rs3);

 // データベースサーバの切断
 mysql_close($db);

?>
</body>
</html>

 結果は、たとえば以下のように表示されます。


 

4.12 集約関数

■フィールド値に対する演算

 参照したレコードの特定のフィールド名に着目して、そのフィールド名の値が数値の場合、最大値、最小値、平均値などの演算を行うことができます。このような演算を行う関数を集約関数あるいは集合関数と呼びます。

 たとえば、フィールド値の平均値を計算する場合は、AVG()関数を使います。この集約関数の結果を参照する場合は、mysql_result()関数で、結果セットの最初のレコード(レコード番号=0)の最初のフィールド(フィールド番号=0)を参照します。

SQL文 = "SELECT AVG(フィールド名) FROM テーブル名";

結果ID = mysql_query(SQL文、接続ID);

PHPの変数 = mysql_result(結果ID,0,0);

■一時変数

 集約関数の結果はRDB内の一時変数に格納することができます。一時変数はフィールド名と同様に参照することができます。

SQL文= "SELECT AVG(フィールド名) AS 一時変数名"
     . " FROM テーブル名";

結果ID = mysql_query(SQL文、接続ID);

連想配列変数 = mysql_fetch_assoc(結果ID, 一時変数名);

■複数の集約関数の同時利用

 集約関数は複数同時に使うことも可能です。集約関数名の間は「,」(カンマ)で区切ります。

SQL文= "SELECT 集約関数名1(フィールド名) AS 一時変数名1,"
     . "     集約関数名2(フィールド名) AS 一時変数名2,"
     . "     集約関数名3(フィールド名) AS 一時変数名3"
     . " FROM テーブル名";

結果ID = mysql_query(SQL文、接続ID);

連想配列変数 = mysql_fetch_assoc(結果ID, 一時変数名);

 

 以上のサンプルファイル「avg.php」を以下に示します。

「avg.php」

<?php
// インクルードファイルの読み込み
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>avg.php</title>
</head>
<body>
<?php

 // データベースサーバへの接続・データベースの選択
 $db = mysql_connect('localhost','webapl','pass1234');
 $db_name = 'db_hanbai_kanri';
 mysql_select_db($db_name,$db);

 // 処理対象テーブル
 $tbl_name = "tbl_shouhin_hyou3";
 show_records($db_name,$tbl_name,$db);
 print "<br>\n";

 // 集約関数
 // 平均値の計算(AVG()関数)
 $fld_name = 'tanka';
 $str_sql = "SELECT AVG({$fld_name}) FROM {$tbl_name} ;";
 $rs = mysql_query($str_sql,$db);

 print "\"{$str_sql}\";<br>\n";

 // 計算結果の参照
 $flt_average = mysql_result($rs,0,0);

 // 計算結果の表示
 print "{$fld_name}の平均値<br>\n";
 print "AVG({$fld_name}) = {$flt_average}<br><br>\n";

 // 一時変数「average」の使用
 $str_sql = "SELECT AVG({$fld_name}) AS average "
      . " FROM {$tbl_name} ;";
 $rs2 = mysql_query($str_sql,$db);

 print "\"{$str_sql}\";<br>\n";

 // 計算結果の参照
 $arr_results = array();
 $arr_results = mysql_fetch_assoc($rs2);
 $flt_average = $arr_results['average'];

 // 計算結果の表示
 print "{$fld_name}の平均値<br>\n";
 print "average = {$flt_average}<br><br>\n";

 // レコード数と最大値、最小値の計算
 $str_sql = "SELECT COUNT({$fld_name}) AS レコード数, "
      . " MIN({$fld_name}) AS min_単価, "
      . " MAX({$fld_name}) AS max_単価"
      . " FROM {$tbl_name} ;";
 $rs3 = mysql_query($str_sql,$db);

 print "\"{$str_sql}\";<br>\n";

 // 計算結果の参照
 $arr_results = array();
 $arr_results = mysql_fetch_assoc($rs3);
 $num_records = $arr_results['レコード数'];
 $min_price  = $arr_results['min_単価'];
 $max_price  = $arr_results['max_単価'];

 print "<table border=1 cellpadding=0 cellspacing=0>\n";
 print "<tr>\n";
 print "<td>レコード数</td>";
 print "<td align=right>{$num_records}</td>\n";
 print "</tr>\n";
 print "<tr>\n";
 print "<td>最小値</td>";
 print "<td align=right>{$min_price}</td>\n";
 print "</tr>\n";
 print "<tr>\n";
 print "<td>最大値</td>";
 print "<td align=right>{$max_price}</td>\n";
 print "</tr>\n";
 print "</table>\n";

 // 結果セット(結果ID)の開放
 mysql_free_result($rs1);
 mysql_free_result($rs2);
 mysql_free_result($rs3);

 // データベースサーバの切断
 mysql_close($db);

?>
</body>
</html>

 結果は、たとえば以下のように表示されます。

 

4.13 グループ化

■GROUP BY句

 あるフィールド名に着目し、そのフィールド値が同じレコードを部分集合としてグループ化することができます。たとえば、アンケート結果で「賛成」と答えた人のグループと「反対」と答えた人」のグループに分けるような場合です。一般には、その部分集合ごとにある演算を行います。グループ化する場合は、「GROUP BY」句を使います。たとえば、次のような構文とします。

SELECT フィールド名, 集約関数, FROM テーブル名 
  GROUP BY フィールド名

 次の例では、フィールド名「hinmoku」に着目し、同じ「hinmoku」の値のレコードをグループ化し、各グループのレコード数を計数しています。

$str_sql = "SELECT hinmoku,COUNT(*) FROM tbl_shouhin GROUP BY hinmoku;";
$rs   = mysql_query($str_sql,$db);

 次の例は、グループごとの「tanka」の合計値を計算しています。

$str_sql = "SELECT hinmoku,SUM(tanka) FROM tbl_shouhin GROUP BY hinmoku;";
$rs   = mysql_query($str_sql,$db);

■HAVING句

 また、グループごとの演算結果についてある条件にあったグループのみを参照(抽出)することができます。この場合はWHERE句でなくHAVING句を使います。

SELECT フィールド名, 集約関数, FROM テーブル名 GROUP BY フィールド名
  HAVING グループに対する条件式

 次の例では、「tanka」の合計値が800より大きいグループのみ参照しています。

$str_sql = "SELECT hinmoku,SUM(tanka) FROM tbl_shouhin GROUP BY hinmoku"
      . "HAVING SUM(tanka) > 800;";
$rs   = mysql_query($str_sql,$db);

 

 サンプルファイル「group.php」を以下に示します。

「group.php」

<?php
// インクルードファイルの読み込み
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>group.php</title>
</head>
<body>
<?php

 // データベースサーバへの接続・データベースの選択
 $db = mysql_connect('localhost','webapl','pass1234');
 $db_name = 'db_hanbai_kanri';
 mysql_select_db($db_name,$db);

 // 処理対象テーブル
 $tbl_name = "tbl_shouhin";
 show_records($db_name,$tbl_name,$db);
 print "<br>\n";

 // グループ化
 $str_sql1 = "SELECT hinmoku,COUNT(*) FROM tbl_shouhin"
      . " GROUP BY hinmoku;";
 $rs1 = mysql_query($str_sql1,$db);

 print "\"{$str_sql1}\";<br>\n";

 // 結果セットの表示
 show_rs($rs1,$db);
 print "<br>\n";

 // グループ化
 $str_sql2 = "SELECT hinmoku,SUM(tanka) FROM tbl_shouhin"
      . " GROUP BY hinmoku;";
 $rs2 = mysql_query($str_sql2,$db);

 print "\"{$str_sql2}\";<br>\n";

 // 結果セットの表示
 show_rs($rs2,$db);
 print "<br>\n";

 // HAVING句
 $str_sql3 = "SELECT hinmoku,SUM(tanka) FROM tbl_shouhin"
      . " GROUP BY hinmoku"
      . " HAVING SUM(tanka) > 800;";
 $rs3 = mysql_query($str_sql3,$db);

 print "\"{$str_sql3}\";<br>\n";

 // 結果セットの表示
 show_rs($rs3,$db);
 print "<br>\n";

 // 結果セット(結果ID)の開放
 mysql_free_result($rs1);
 mysql_free_result($rs2);
 mysql_free_result($rs3);

 // データベースサーバの切断
 mysql_close($db);

?>
</body>
</html>

 結果は、たとえば以下のように表示されます。

 

4.14 テーブル結合と相関名

■自然結合(NATURAL JOIN)

 データの正規化により作成されたテーブルは冗長性のない合理的な構造となりますが、逆に人間にはわかりにくいものとなっています。そこで、実際の利用では、正規化により分割されたテーブルを結合して、わかりやすく表示します。これを表結合といいます。

次のテーブル「tbl_uriage_meisai」とテーブル「tbl_shouhin1」を例にとります。

「tbl_uriage_meisai」
+-------------+--------------+-------+
| denpyo_code | shouhin_code | kosuu |
+-------------+--------------+-------+
| 1101     | 100     |  100 |
| 1101     | 110     |  150 |
| 1120     | 120     |  80 |
| 1128     | 130     |  100 |
+-------------+--------------+-------+
4 rows in set (0.00 sec)

「tbl_shouhin1」
+--------------+--------------+-------+
| shouhin_code | shouhin_mei | tanka |
+--------------+--------------+-------+
| 100     | チョコレート |  200 |
| 110     | キャンディ  |  300 |
| 120     | せんべい   |  250 |
| 130     | ケーキ    |  400 |
| 140     | ガム     |  100 |
+--------------+--------------+-------+
4 rows in set (0.00 sec)

 テーブル「tbl_uriage_meisai」には「shouhin_code」はありますが、第2正規化を行っているので、商品名は別途テーブル「tbl_shouhin1」を参照しないとわかりません。
 たとえば、テーブル「tbl_uriage_meisai」の「shouhin_code」='100'の商品名は、「tbl_shouhin1」の「shouhin_code」='100'のレコードの「shouhin_mei」を参照して、「チョコレート」であることがわかります。テーブル「tbl_uriage_meisai」の「shouhin_code」フィールドのとなりに、「shouhin_mei」フィールドがあると、人間にとってわかりやすくなります。

そこで、テーブル「tbl_uriage_meisai」とテーブル「tbl_shouhin1」を結合させることを考えます。

 テーブルを結合する第1の方法は、自然結合のための「NATURAL JOIN」句を使う方法です。

SELECT * FROM テーブル1 NATURAL JOIN テーブル2

 自然結合では、テーブル1とテーブル2両方のテーブルにおのおの同じフィールド名がある必要があります。上のテーブルの例ではフィールド名「商品コード」が両方のテーブルにあることがわかります。その同じフィールド名の同じフィールド値を持つレコードどうしを結合します。

 サンプルファイル「natural_join.php」を以の下に示します。

「natural_join.php」

<?php
// インクルードファイルの読み込み
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>natural_join.php</title>
</head>
<body>
<?php

 // データベースサーバへの接続・データベースの選択
 $db = mysql_connect('localhost','webapl','pass1234');
 $db_name = 'db_hanbai_kanri';
 mysql_select_db($db_name,$db);

 // 処理対象テーブル
 $tbl_name1 = "tbl_uriage_meisai";
 print "「{$tbl_name1}」<br>\n";
 show_records($db_name,$tbl_name1,$db);
 print "<br>\n";

 $tbl_name2 = "tbl_shouhin1";
 print "「{$tbl_name2}」<br>\n";
 show_records($db_name,$tbl_name2,$db);
 print "<br>\n";

 // 自然結合(NATURAL JOIN句)
 $str_sql1 = "SELECT * FROM {$tbl_name1}"
      . "NATURAL JOIN {$tbl_name2};";
 $rs1 = mysql_query($str_sql1,$db);

 print "\"{$str_sql1}\"<br>\n";

 // 結果セットの表示
 show_rs($rs1,$db);
 print "<br>\n";

 // 結果セット(結果ID)の開放
 mysql_free_result($rs1);
 

 // データベースサーバの切断
 mysql_close($db);

?>
</body>
</html>

 結果は、たとえば以下のように表示されます。


■内部結合(INNER JOIN)

 テーブルを結合する第2の方法は、内部結合のための「INNER JOIN」句を使う方法です。

SELECT * FROM テーブル1 INNER JOIN テーブル2
   ON 結合条件式

 「INNER JOIN」では、「ON」の後に2つのテーブルを結合するための結合条件式を記述する必要があります。一般にはテーブル1のフィールド名1とテーブル2のフィールド名2が等しいレコードを結合する場合には結合条件式は次のようになります。

ON テーブル1.フィールド名1 = テーブル2.フィールド名2

  サンプルファイル「inner_join.php」を以の下に示します。

「inner_join.php」

<?php
// インクルードファイルの読み込み
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>inner_join.php</title>
</head>
<body>
<?php

 // データベースサーバへの接続・データベースの選択
 $db = mysql_connect('localhost','webapl','pass1234');
 $db_name = 'db_hanbai_kanri';
 mysql_select_db($db_name,$db);

 // 処理対象テーブル
 $tbl_name1 = "tbl_uriage_meisai";
 $tbl_name2 = "tbl_shouhin1";
 
 // 内部結合(INNER JOIN句)
 $str_sql1 = "SELECT * FROM {$tbl_name1}"
      . " INNER JOIN {$tbl_name2}"
      . " ON {$tbl_name1}.shouhin_code"
      . "  = {$tbl_name2}.shouhin_code;";
 $rs1 = mysql_query($str_sql1,$db);

 print "\"{$str_sql1}\"<br>\n";

 // 結果セットの表示
 show_rs($rs1,$db);
 print "<br>\n";

 // 結果セット(結果ID)の開放
 mysql_free_result($rs1);
 

 // データベースサーバの切断
 mysql_close($db);

?>
</body>
</html>

 結果は、たとえば以下のように表示されます。

 「INNER JOIN」の場合は、結合条件を明示的に記述するので、両方のテーブルで比較するフィールド名が異なっていても結合することができます。たとえば、上の例で、「tbl_uriage_meisai」テーブルの「shouhin_code」フィールド名が「shouhinID」の場合は、次のような条件式を記述すればいいことになります。


$str_sql1 = "SELECT * FROM {$tbl_name1}"
      . " INNER JOIN {$tbl_name2}"
      . " ON {$tbl_name1}.shouhinID"
      .   = {$tbl_name2}.shouhin_code
;";

■左外部結合(LEFT OUTER JOIN)

 テーブルを結合する第3の方法は、左外部結合のための「LEFT OUTER JOIN」句を使う方法です。

SELECT * FROM テーブル1 LEFT OUTER JOIN テーブル2
   ON 結合条件式

 内部結合では、結合条件式に合致するレコードのみが結合して参照されます。それに対して、外部結合では、どちらかのテーブルのレコードはすべて表示されます。
  FROM句の後に記述されているテーブル1のレコードをすべて参照する結合方法を左外部結合といいます。それに対して、JOIN句の後に記述されているテーブル2のレコードをすべて参照する結合方法を右外部結合といいます。
  つまりSQL文で先に(左側に)記述されているテーブルのすべてのレコードを参照する場合を左外部結合といっているのです。

 SQL文のサンプルを下記に示します。サンプルファイル「inner_join.php」でSQL文のみを下記に置き換えたサンプルファイルを「left_join.php」とします。

「left_join.php」のSQL文

// 左外部結合(LEFT OUTER JOIN句)
$str_sql1 = "SELECT * FROM {$tbl_name1}"
     . " LEFT OUTER JOIN {$tbl_name2}"
     . " ON {$tbl_name1}.shouhin_code = {$tbl_name2}.shouhin_code;";
$rs1 = mysql_query($str_sql1,$db);

 結果は、たとえば以下のように表示されます。

■右外部結合(RIGHT OUTER JOIN)

 テーブルを結合する第4の方法は、右外部結合のための「RIGHT OUTER JOIN」句を使う方法です。

SELECT * FROM テーブル1 RIGHT OUTER JOIN テーブル2
   ON 結合条件式

 右外部結合では、SQL文で右側に記述されたテーブル2のレコードは、テーブル1の状態いかんにかかわらずすべて参照されます。

 SQL文のサンプルを下記に示します。サンプルファイル「left_join.php」でSQL文のみを下記に置き換えたサンプルファイルを「right_join.php」とします。

「right_join.php」のSQL文

// 左外部結合(LEFT OUTER JOIN句)
$str_sql1 = "SELECT * FROM {$tbl_name1}"
     . " RIGHT OUTER JOIN {$tbl_name2}"
     . " ON {$tbl_name1}.shouhin_code = {$tbl_name2}.shouhin_code;";
$rs1 = mysql_query($str_sql1,$db);

 結果は、たとえば以下のように表示されます。

 最後のレコードに対応するshouhin_code='140'のレコードは左のテーブル「tbl_uriage_meisai」にはありませんが、右のテーブル「tbl_shouhin1」にはあるので、右外部結合の結果セットには表示されているのがわかります。なお、対応する「tbl_uriage_meisai」の「denpy_code」と「kosuu」のフィールド値はNULL値が表示されます。

■SELECT文によるテーブルの結合

 テーブルを結合する第5の方法は、SELECT文を使う方法です。SELECT文で自然結合を行うには、以下の構文を使います。

SELECT   テーブル1.フィールド名1, テーブル1.フィールド名2, ・・・,テーブル1.フィールド名m,
        テーブル2.フィールド名1, テーブル2.フィールド名2, ・・・,テーブル2.フィールド名n,
  FROM  テーブル1, テーブル2
  WHERE テーブル1.フィールド名x = テーブル2.フィールド名y

 複数のテーブルのフィールド名を混在して使用する場合は、どのテーブルのどのフィールド名かが分かるように、「テーブル名.フィールド名」のようにテーブル名とフィールド名を「.」(半角ピリオド)で結合した表記を使います。

 FROM句には結合する複数のテーブル名を「,」(カンマ)で区切って記述します。結合条件式は、WHERE句の中に記述します。

 SQL文のサンプルを下記に示します。サンプルファイル「right_join.php」でSQL文のみを下記に置き換えたサンプルファイルを「select_join.php」とします。

「select_join.php」のSQL文

// SELECT文による自然結合
$str_sql1 = "SELECT {$tbl_name1}.denpyo,"
     .    "{$tbl_name1}.shouhin_code,"
     .    "{$tbl_name1}.kosuu,"
     .    "{$tbl_name2}.shouhin_mei,"
     .    "{$tbl_name2}.tanka"
     .  " FROM {$tbl_name1}, {$tbl_name2}"
     .  " WHERE {$tbl_name1}.shouhin_code = {$tbl_name2}.shouhin_code;";
$rs1 = mysql_query($str_sql1,$db);

 結果は、たとえば以下のように表示されます。

■相関名

 フィールド名を「テーブル名.フィールド名」と記述する方法では、表記が長くわかりづらくなるので、「相関名」を使ってより簡単に表記することができます。

 相関名とはたとえば、テーブル「tbl_uriage_meisai」を1文字のアルファベット「M」で表記するような方法です。相関名は、FROM句内で、テーブル名の後に半角スペース1個以上で区切って相関名となるアルファベットを挿入することで定義します。

 相関名を使ったSQL文のサンプルを下記に示します。サンプルファイル「select_join.php」でSQL文のみを下記に置き換えたサンプルファイルを「select_alias_join.php」とします。

「select_alias_join.php」のSQL文

// SELECT文による自然結合(相関名の使用)
$str_sql1 = "SELECT M.denpyo_code,"
     .    "M.shouhin_code,"
     .    "M.kosuu,"
     .    "S.shouhin_mei,"
     .    "S.tanka"
     .  " FROM {$tbl_name1} M, {$tbl_name2} S"
     .  " WHERE M.shouhin_code = S.shouhin_code;";
$rs1 = mysql_query($str_sql1,$db);

 結果は、たとえば以下のように表示されます。

 

4.15 ビュー

 SELECT文によるSQL文をあらかじめビューとして定義しておくことができます。つまり、SQL文を実行した結果リソースであって、行と列からなる仮想的なテーブルです。ビューとしての具体的なデータの集合がデータベース内にある訳でなく、ビューを呼び出したときに、その場でビューで定義したSQL文が実行され一時的に結果リソースが生成されるに過ぎません。

 ビューの定義には、SQLコマンドのCREATE VIEW文を使用します。

CREATE VIEW ビュー名 AS SELECT文

 定義したビューをテーブルとみなして、SQL文を実行することが可能です。

 ビューのサンプルを下記に示します。

「view.php」

<?php
// インクルードファイルの読み込み
include "common_mysql.php";

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP">
<title>select_alias_join.php</title>
</head>
<body>
<?php

// データベースサーバへの接続・データベースの選択
$db = mysql_connect('localhost','webapl','pass1234');
$db_name = 'db_hanbai_kanri';
mysql_select_db($db_name,$db);

// 処理対象テーブル
$tbl_name1 = "tbl_uriage_meisai";

$tbl_name2 = "tbl_shouhin1";

// SELECT文による結合(相関名の使用)
$str_sql1 = "SELECT M.denpyo_code,"
. "M.shouhin_code,"
. "M.kosuu,"
. "S.shouhin_mei,"
. "S.tanka"
. " FROM {$tbl_name1} M, {$tbl_name2} S"
. " WHERE M.shouhin_code = S.shouhin_code";

// VIEWの定義用SQL文
$str_sql2 = "CREATE VIEW viw_uriage_meisai AS $str_sql1;";

// VIEWの定義用SQL文の実行
$rs2 = mysql_query($str_sql2,$db);
print "\"{$str_sql2}\"<br><br>\n";

// ビューを使ったSQL文(その1)
$str_sql3 = "SELECT * FROM viw_uriage_meisai;";

$rs3 = mysql_query($str_sql3,$db);
print "\"{$str_sql3}\"<br>\n";
// 結果セットの表示
show_rs($rs3,$db);
print "<br>\n";

// ビューを使ったSQL文(その2)
$str_sql4 = "SELECT * FROM viw_uriage_meisai WHERE tanka >= 300;";

$rs4 = mysql_query($str_sql4,$db);
print "\"{$str_sql4}\"<br>\n";
// 結果セットの表示
show_rs($rs4,$db);
print "<br>\n";

// 結果セット(結果ID)の開放
mysql_free_result($rs3);
mysql_free_result($rs4);

// データベースサーバの切断
mysql_close($db);

?>
</body>
</html>

 結果を以下に示します。

 


前へ | 目次へ |次へ  | YCポータルサイト

執筆 山田豊通
更新日: 2006年11月22日