データベースに2つのテーブルがあります。
NEWS( 'id'-ニュースID、 'user'-作成者のユーザーID)
USERS( 'id'-ユーザーID)
_SELECT * FROM news JOIN users ON news.user = user.id
_を作成したいのですが、PHPのような結果になりました:
$row = mysql_fetch_array($result)
、および_$row['column-name']
_で列名を取得...同じ列名を持つニュースIDとユーザーIDを取得するにはどうすればよいですか?
更新:素早い回答をありがとう。エイリアスが最善の解決策のようです。
選択している列のエイリアスを設定できます。
$query = 'SELECT news.id AS newsId, user.id AS userId, [OTHER FIELDS HERE] FROM news JOIN users ON news.user = user.id'
数値インデックス($row[0]
)以上の場合、MySQLでAS
を使用します。
SELECT *, user.id AS user_id FROM ...
私はこれを理解しました。これはおそらく悪い習慣ですが、この場合はうまくいきました。
私は、テーブルプレフィックスを使用してすべての列名をエイリアスしたり、書き出したりしたくない怠け者の1人です。
Selectステートメントでtable_name.*
を使用して、特定のテーブルからすべての列を選択できます。
列名が重複している場合、mysqlは最初から最後まで上書きします。最初に複製された列名のデータは、その列名が再び検出されると上書きされます。したがって、最後に来る重複した列名が優先されます。
それぞれが重複した列名を含む3つのテーブルを結合する場合、selectステートメント内のテーブルの順序によって、重複する列に対して取得するデータが決まります。
例:
SELECT table1.* , table2.* , table3.* FROM table1 LEFT JOIN table2 ON table1.dup = table2.dup LEFT JOIN table3 ON table2.dup = table3.dup;
上記の例では、dup
の値はtable3
から取得されます。
dup
をtable1
の値にしたい場合はどうなりますか?
次に、これを行う必要があります:
SELECT table3.* , table2.* , table1.* FROM table1 LEFT JOIN table2 ON table1.dup = table2.dup LEFT JOIN table3 ON table2.dup = table3.dup;
これで、table1
が最後に来るため、dup
の値はtable1の値になります。
dup
に必要な値を取得しましたが、おかしな列を1つずつ書き出す必要はなく、すべての列を使用できます。わーい!
dup
の値は3つのテーブルすべてで同じである必要がありますが、table3
にdup
に一致する値がない場合はどうなりますか?その場合、最初の例ではdup
が空白になり、それは残念です。
別のヒント:よりきれいなPHPコードが必要な場合は、データベースにVIEWを作成できます。
例えば:
CREATE VIEW view_news AS
SELECT
news.id news_id,
user.id user_id,
user.name user_name,
[ OTHER FIELDS ]
FROM news, users
WHERE news.user_id = user.id;
PHPの場合:
$sql = "SELECT * FROM view_news";
@ジェイソン。 phpがmysqlではなく犯人であることを除いて、あなたは正しいです。 JOIN
をMysql Workbenchに配置すると、まったく同じ名前(テーブルごとに1つ)で3つの列が得られますが、同じデータではありません(テーブルにない場合はnull
になります) JOIN
)に一致します。
Phpでは、mysql_fetch_array()
で_MYSQL_NUM
_を使用すると、すべての列が取得されます。問題は、mysql_fetch_array()
を_MYSQL_ASSOC
_とともに使用する場合です。次に、その関数内で、phpは次のように戻り値を構築します。
_$row['dup'] = [value from table1]
_
以降.
_$row['dup'] = [value from table2]
_
...
_$row['dup'] = [value from table3]
_
したがって、table3から値のみを取得します。問題は、mysqlの結果セットに同じ名前の列を含めることができるが、phpの連想配列では配列内の重複キーが許可されないことです。データがPHPで連想配列に保存されると、一部の情報が静かに失われます...
次のようなことができます
SELECT news.id as news_id, user.id as user_id ....
その後 $row['news_id']
はニュースIDであり、$row['user_id']
はユーザーIDになります
動的テーブルでも同じ問題が発生しました。 (結合できるようにidを持っていると想定されているが、残りのフィールドについては想定されていないテーブル。)この場合、エイリアスを事前に知りません。
そのような場合、最初にすべての動的テーブルのテーブル列名を取得できます。
$tblFields = array_keys($zendDbInstance->describeTable($tableName));
ここで、$ zendDbInstanceはZend_Dbのインスタンスです。または、Zendに依存しないために、ここで関数のいずれかを使用できます php pdo:テーブルの列名を取得
次に、すべての動的テーブルでエイリアスを取得し、エイリアスを必要としないものに$ tableName。*を使用できます。
$aliases = "";
foreach($tblKeys as $field)
$aliases .= $tableName . '.' . $field . ' AS ' . $tableName . '_' . $field . ',' ;
$aliases = trim(',', $aliases);
このプロセス全体を1つの汎用関数にまとめて、よりクリーンなコードにするか、必要に応じてより遅延させることができます:)
エイリアスを作成したくない場合は、テーブル名にプレフィックスを付けることもできます。
これにより、クエリの生成をより自動化できます。また、select *を使用しないことをお勧めします(フィールドを選択するよりも明らかに遅いですneedさらに、必要なフィールドに明示的に名前を付けるだけです。
SELECT
news.id, news.title, news.author, news.posted,
users.id, users.name, users.registered
FROM
news
LEFT JOIN
users
ON
news.user = user.id