PHPとMySQLでサイトを制作しているのですが、データの表示の仕方で悩んでいます。


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;

}

のような感じで表示してますが、もっと簡単に記述する方法はありませんか?
うまく説明することが出来ないのですが、理解していただいた方がいたら解説などをいれてお願いします。

回答の条件
  • 1人10回まで
  • 登録:
  • 終了:2006/06/20 19:14:42
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:vector_xenon No.3

回答回数113ベストアンサー獲得回数4

ポイント60pt

前回の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の”.”の前はテーブルの指定ですので。


また、アスタリスクは極力使わない方がよろしいですよ。

id:black_kenchan

フィールドがたくさんある場合もアスタリスクを使わないで指定していったほうが良いのですか?

2006/06/16 12:43:44

その他の回答8件)

id:Chiether No.1

回答回数40ベストアンサー獲得回数1

ポイント10pt

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

を参考にしてみてください。

id:black_kenchan

selectの部分でアスタリスクは使わないほうが良いのでしょうか?

テーブルAとテーブルBの各フィールドで同じ名前のものがある場合も無い場合もasで名前をつけたほうが良いのでしょうか?

2006/06/16 12:42:36
id:sisya No.2

回答回数24ベストアンサー獲得回数2

ポイント10pt

用は色名を示している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'];

}

id:vector_xenon No.3

回答回数113ベストアンサー獲得回数4ここでベストアンサー

ポイント60pt

前回の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の”.”の前はテーブルの指定ですので。


また、アスタリスクは極力使わない方がよろしいですよ。

id:black_kenchan

フィールドがたくさんある場合もアスタリスクを使わないで指定していったほうが良いのですか?

2006/06/16 12:43:44
id:asuzu No.4

回答回数1ベストアンサー獲得回数0

ポイント10pt

プログラム上であれこれしなくても

select テーブルA.フィールド1, テーブルB.フィールド2

from テーブルA, テーブルB

where テーブルA.フィールド2 = テーブルB.フィールド1

order by テーブルA.フィールド1 desc;

で取り出したいデータを得られると思います。

つまり、2つのテーブルをテーブルA.フィールド2とテーブルB.フィールド1で結合してやれば良いわけです。

id:bonlife No.5

回答回数421ベストアンサー獲得回数75

ポイント10pt

以下のようなやり方で出来ると思います。

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 />";
	}
}

参考になれば幸いです。

id:m-nisi No.6

回答回数159ベストアンサー獲得回数3

ポイント10pt

$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";

}

こんな感じでどうでしょう?

id:vector_xenon No.7

回答回数113ベストアンサー獲得回数4

ポイント10pt

アスタリスクを使わないのは、パフォーマンスの問題です。


一部のデータしか利用しない場合、全部取得するよりも最小限のデータを取得したほうがDBに負担がかかりません。

また、全てのフィールドを取得する際にもアスタリスクを使うよりも指定した方が高速です。


しかしよほど複雑且つフィールドが多い場合でない限りは、体感速度に差はないかと思います。




2の方へのコメントの内容についてですが、取得するフィールド名が同じの場合は別名をつけた方がよいでしょう。

恐らくですが、同じ名前にすると値が上書きされてしまう気がします。

# もしかしたら ['テーブル名.フィールド名'] で取得できるのかもしれませんが。

id:black_kenchan

ありがとうございます。一応出来ました。

しかし、問題が出てきました。

1.テーブルAにフィールド3を追加してWHEREのところに「テーブルA.フィールド3 = '1' OR テーブルA.フィールド3 = '2'と追加したら表示がおかしくなりテーブルAの名前が全部同じになってしまいます。テーブルBのデータのほうは大丈夫なのですが・・・

2006/06/16 13:30:41
id:bonlife No.8

回答回数421ベストアンサー獲得回数75

ポイント10pt

フィールドがたくさんある場合もソースの見通しをよくするために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文中で定義した方が良いのではないでしょうか。

参考になれば幸いです。

id:black_kenchan

ありがとうございます。一応出来ました。

しかし、問題が出てきました。

1.テーブルAにフィールド3を追加してWHEREのところに「テーブルA.フィールド3 = '1' OR テーブルA.フィールド3 = '2'と追加したら表示がおかしくなりテーブルAの名前が全部同じになってしまいます。テーブルBのデータのほうは大丈夫なのですが・・・

2006/06/16 13:30:59
id:vector_xenon No.9

回答回数113ベストアンサー獲得回数4

ポイント10pt

フィールド3がどのような状態なのかわからないので、確証はありませんが、ORを利用したときに()は使用していますか?


-------------

WHERE

 A.フィールド2 = B.フィールド1 AND

 (A.フィールド3 = '1' OR B.フィールド3 = '3')

-------------

  • id:Chiether
    >アスタリスク
    vector_xenonさんの言うとおりですが
    ORACLEだと、厳しく言われる現場もあるのです。 つДT)

    as は 必須ではないですが 結合した時は重複しなくても
    「テーブル名.フィールド名は絶対」
    というのが、長く付き合ってたルールなもので as つけちゃいます。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません