2個のテーブルのデータを合わせて表示するので悩んでいます。
うまく言えなにのですが、
テーブルA
フィールド1 フィールド2
名前1 1
名前2 2
名前3 1
テーブルB
フィールド1 フィールド2
1 赤
2 青
上記のテーブルデータを
名前1 赤
名前2 青
名前3 赤
のように表示させたいのですが、現在は
$sql = "";
$sql .= "select*from テーブルA";
$sql .= " ORDER BY フィールド1 DESC";
$sql .= " LIMIT 0,10";
$rs = mysql_query( $sql, $conn );
while( $rec = mysql_fetch_array( $rs, MYSQL_ASSOC )){
$sql = "";
$sql .= "select*from テーブルB";
$sql .= " WHERE フィールド1 = '{$rec["フィールド2"]}'";
$rs2 = mysql_query( $sql, $conn );
if( $rec2 = mysql_fetch_array( $rs2 ) ){
$MK = $rec2["フィールド2"];
}
print $rec["フィールド1"]." - ".$MK;
}
のような感じで表示してますが、もっと簡単に記述する方法はありませんか?
うまく説明することが出来ないのですが、理解していただいた方がいたら解説などをいれてお願いします。
前回の3の方の答えで合っています。
---------------------------------
SELECT
A.フィールド1 a_field,
B.フィールド2 b_field
FROM
テーブルA A,
テーブルB B
WHERE
A.フィールド2 = B.フィールド1
---------------------------------
$row['a_field']
$row['b_field']
前回これでBのデータしか出ないと仰っておられますが、テーブルの指定を間違えているのでは?
A.フィールド1の”.”の前はテーブルの指定ですので。
また、アスタリスクは極力使わない方がよろしいですよ。
SQLを変更しましょう。
select
テーブルA.フィールド1 as name,
テーブルB.フィールド2 as color,
from
テーブルA, テーブルB
where
テーブルA.フィールド2 = テーブルB.フィールド1
order by
テーブルA.フィールド1
あとはPHPで
$sql = ""; //先ほどのクエリ
$mysql_res = mysql_query( $sql, $conn );
while( $arr = mysql_fetch_array( $mysql_res ) ){
echo $arr["name"] . " - " . $arr["color"] . "\n";
}
これでいけます。
あと。これは条件があって
テーブルAのフィールド1に入っているデータが
テーブルBのフィールド2に入っていない場合等は考慮していません。
これをフォローする場合は、SQLの外部結合と呼ばれるのが必要になります。
( left outer join とか... )
外部結合については長くなる&上手く説明する自信が無いので、
私がお世話になったサイト
http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/mysql_09.htm
を参考にしてみてください。
selectの部分でアスタリスクは使わないほうが良いのでしょうか?
テーブルAとテーブルBの各フィールドで同じ名前のものがある場合も無い場合もasで名前をつけたほうが良いのでしょうか?
用は色名を示しているIDを結合したいんですよね、
前の方が答えてしまっているかもしれませんが、
以下のように書けばお望みの一覧が表示されます
$Query = "select テーブルA.フィールド1 テーブルB.フィールド2";
$Query .= " from テーブルA left outer join テーブルB";
$Query .= " on テーブルA.フィールド2 = テーブルB.フィールド1";
$Res = mysql_query($Query, $conn);
while($Record = mysql_fetch_assoc($Res)){
print $Record['フィールド1']." ".$Record['フィールド2'];
}
前回の3の方の答えで合っています。
---------------------------------
SELECT
A.フィールド1 a_field,
B.フィールド2 b_field
FROM
テーブルA A,
テーブルB B
WHERE
A.フィールド2 = B.フィールド1
---------------------------------
$row['a_field']
$row['b_field']
前回これでBのデータしか出ないと仰っておられますが、テーブルの指定を間違えているのでは?
A.フィールド1の”.”の前はテーブルの指定ですので。
また、アスタリスクは極力使わない方がよろしいですよ。
フィールドがたくさんある場合もアスタリスクを使わないで指定していったほうが良いのですか?
プログラム上であれこれしなくても
select テーブルA.フィールド1, テーブルB.フィールド2
from テーブルA, テーブルB
where テーブルA.フィールド2 = テーブルB.フィールド1
order by テーブルA.フィールド1 desc;
で取り出したいデータを得られると思います。
つまり、2つのテーブルをテーブルA.フィールド2とテーブルB.フィールド1で結合してやれば良いわけです。
以下のようなやり方で出来ると思います。
SQL、表示部分のみでも十分かと思いましたが、念のために全ソースを書いておきます。
SQLと表示処理の部分を中心に確認してみてください。
全ての文字コードがUTF-8の場合の例ですので、環境が異なる場合は適宜修正してください。
<?php // HTML出力用設定 mb_http_output('UTF-8'); header("Content-Type: text/html; charset=UTF-8"); // HTMLのヘッダー部分出力 print <<<EOF <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>MySQL検索結果の表示テスト(テーブルで表示)</title> <style type="text/css"> table,td { border-style:solid; border-color:black; border-width:1px; } td { padding:0.5em ; } </style> </head> <body> EOF; // MySQLに接続 (サーバ名、ユーザーID、パスワードは適宜変更) $con = mysql_connect("localhost","user","password") or die("MySQLに接続できません。"); // データベースを選択 (例では test を選択) mysql_select_db('test'); $sql = "SET CHARACTER SET UTF8"; $result = mysql_query($sql); /* SQLで問合せ (例ではテーブル名を tablea, tableb とする) 2つのテーブルを結合し、検索を行う 後で検索結果を名前で取得できるように列にASで別名をつけておく */ $sql = "SELECT tablea.field1 AS name, tableb.field2 AS color"; $sql .= " FROM tablea, tableb"; $sql .= " WHERE tablea.field2 = tableb.field1"; $sql .= " ORDER BY tablea.field1;"; $result = mysql_query($sql); // 以下表示処理 if (!$result) { print "検索結果を取得できませんでした。"; } else { print "<table>"; while($row=mysql_fetch_array($result)){ print "\n <tr>\n <td>" . $row['name'] . "</td>\n <td>" . $row['color'] . "</td>\n </tr>"; } print "</table>\n"; } // HTMLのフッター部分出力 print <<<EOF </body> </html> EOF; ?>
表示結果をテーブルにする必要がないのであれば、表示処理の部分を以下のように書き換えれば良いです。
if (!$result) { print "検索結果を取得できませんでした。"; } else { while($row=mysql_fetch_array($result)){ print $row['name'] . " : " . $row['color'] . "<br />"; } }
参考になれば幸いです。
$sql = "select テーブルA.フィールド1 as 名前,テーブルB.フィールド2 as 色 from テーブルA,テーブルB where テーブルA.フィールド2 = テーブルB.フィールド1";
$rs = mysql_query( $sql, $conn );
while( $rec = mysql_fetch_array( $rs, MYSQL_ASSOC )){
print "{$rec['名前']} {$rec['色']}\n";
}
こんな感じでどうでしょう?
アスタリスクを使わないのは、パフォーマンスの問題です。
一部のデータしか利用しない場合、全部取得するよりも最小限のデータを取得したほうがDBに負担がかかりません。
また、全てのフィールドを取得する際にもアスタリスクを使うよりも指定した方が高速です。
しかしよほど複雑且つフィールドが多い場合でない限りは、体感速度に差はないかと思います。
2の方へのコメントの内容についてですが、取得するフィールド名が同じの場合は別名をつけた方がよいでしょう。
恐らくですが、同じ名前にすると値が上書きされてしまう気がします。
# もしかしたら ['テーブル名.フィールド名'] で取得できるのかもしれませんが。
ありがとうございます。一応出来ました。
しかし、問題が出てきました。
1.テーブルAにフィールド3を追加してWHEREのところに「テーブルA.フィールド3 = '1' OR テーブルA.フィールド3 = '2'と追加したら表示がおかしくなりテーブルAの名前が全部同じになってしまいます。テーブルBのデータのほうは大丈夫なのですが・・・
フィールドがたくさんある場合もソースの見通しをよくするためにSELECT文中でフィールドは全て定義した方が良いです。
(結合した場合は別名を付与してください。)
どのフィールドの値を取得したのかがDBのテーブル構造をチェックしなくてもソースを見ただけで分かります。
その結果、処理のイメージが湧きやすくなります。
どうしてもSELECTでアスタリスクを使いたい場合は以下のようにしてみてください。
$sql = "SELECT *"; $sql .= " FROM tablea, tableb"; $sql .= " WHERE tablea.field2 = tableb.field1"; $sql .= " ORDER BY tablea.field1;"; $result = mysql_query($sql); // 以下表示処理 if (!$result) { print "検索結果を取得できませんでした。"; } else { while($row=mysql_fetch_array($result)){ print $row[1] . " : " . $row[2] . " : " $row[3] . " : " . $row[4] . "<br />"; } }
mysql_fetch_arrayのデフォルトでは2通りの方法でデータを参照できます。
フィールド名の連想配列ではなく、列番号での参照が可能です。
2つのテーブルを結合し、SELECTではアスタリスクでデータを取得した場合、列番号はFROM句で指定したテーブルの順序になります。
つまり、上記の例ではtableaの列1、列2、列3...の後、tablebの列1、列2、列3...となります。
tablebの列1の値を取得した場合、tableaの列数+1を配列の添え字として指定する必要があります。
結局このやり方の方が分かりづらくなってしまうような気がします。
やはり全てのフィールドをSELECT文中で定義した方が良いのではないでしょうか。
参考になれば幸いです。
ありがとうございます。一応出来ました。
しかし、問題が出てきました。
1.テーブルAにフィールド3を追加してWHEREのところに「テーブルA.フィールド3 = '1' OR テーブルA.フィールド3 = '2'と追加したら表示がおかしくなりテーブルAの名前が全部同じになってしまいます。テーブルBのデータのほうは大丈夫なのですが・・・
フィールド3がどのような状態なのかわからないので、確証はありませんが、ORを利用したときに()は使用していますか?
-------------
WHERE
A.フィールド2 = B.フィールド1 AND
(A.フィールド3 = '1' OR B.フィールド3 = '3')
-------------
フィールドがたくさんある場合もアスタリスクを使わないで指定していったほうが良いのですか?