->joinAdd() – JOIN クエリを生成するために他の DataObject を追加する


void $DB_DataObject->joinAdd ( object $dataobject , string $joinType , string $joinAs , string $joinCol )


他の DataObject を追加して JOIN クエリを生成します。 このメソッドを使用するときは注意してください。 そのままのクエリの方が joinAddメソッドを使用するよりも 分かりやすいかも知れません。

このメソッドを実装してくれた Stijn de Reede に感謝します。


  • object $obj - 結合されるオブジェクトを 指定します。 (値がない場合、結合がクリアされます)

  • string $joinType - "LEFT" | "INNER " | "RIGHT" | ""

    INNER がデフォルトで、"" は結合やリンクが WHERE 句に追加されず、単純に select ... from a,b,c を実行します。

    注意: 'LEFT' は LEFT OUTER と等価です。

  • string $joinAs - テーブルを別名で扱いたい場合、 二次テーブルからカラムを複数選択したいときに役に立つでしょう

  • string $joinCol - このオブジェクトのテーブルでマッチさせたいカラムを指定します。 このテーブルを子オブジェクトの複数箇所にリンクする場合に必要です。


    user->friend (is a id of a person)
    user->mother (is a id of another person)


This function can not be called statically.

以下の例はテストされていません。DB_DataObject::debugLevel(1) を使用し、 これを使用したときに何が行われているかを理解し、 著者により良い例を送ってください。



// (links.ini が正しく設定されていることを前提に)
// 24 番の製品のすべての画像を取得します

$i = new DataObject_Image();
$pi = new DataObjects_Product_image();
$pi->product_id 24// 製品 ID を 24 に設定します
$i->joinAdd($pi); // product_image を接続します
while (
$i->fetch()) {
// 何かの処理を行います

結果の SQL

  LEFT JOIN product_image 
    ON (image.id = product_image.image_id)
  WHERE product_image.id = 24

より複雑な JOIN クエリ

// ふたつの JOIN を使用する例
// 製品あるいは製品グループに関連するすべての画像を取得します
$i = new DataObject_Image();
$pi = new DataObject_Product_image();
$pgi = new DataObject_Productgroup_image();
while (
$i->fetch()) {
// 何かの処理を行います

結果の SQL

SELECT * FROM image 
  LEFT JOIN product_image 
      ON (image.id = product_image.image_id)
  LEFT JOIN productgroup 
      ON (image.id = productgroup_image.image_id);
クエリの取得 コンポーネントを構築する (通常は結合のため) (Previous) オーバーロードを用いた自動的な set系・get系メソッド (Next)
Last updated: Sat, 19 Apr 2014 — Download Documentation
Do you think that something on this page is wrong? Please file a bug report or add a note.
View this page in:

User Notes:

Note by: avkachalov@gmail.com
There is a possibility to join using complex conditions. You can pass second and other arguments as an associative array and an extra argument useWhereAsOn becomes availabile in that case.

See sources for full documentation. Quote:

If second Argument is array, it is assumed to be an associative
array with arguments matching below = eg.
'joinType' => 'INNER',
'joinAs' => '...'
'joinCol' => ....
'useWhereAsOn' => false
Note by: alan@akbkhome.com
You may want to use $do->selectAs($joinedObj, 'prefix_%s') with the above example.
Note by: johng@neutralize.com

This took me ages and ages to figure out...

You can do some nice JOINs, so in the above example we can grab the image, product name and group name:

// -------------------------------------------------
// an example with 2 joins
// get all the images linked with products or productgroups
// and the product name and group name.
$i = new DataObject_Image();
$pi = new DataObject_Product_image();
$pgi = new DataObject_Productgroup_image();

$i->selectAdd( 'image, product.name as p_name, product_group.name as g_name' );

while ($i->fetch()) {
echo $i->image;
echo $i->p_name;
echo $i->g_name;

// -------------------------------------------------

Note how the image object has new attributes called p_name and g_name? How cool is that?!

You may need to look at the syntax of addJoin, because you can also do:

// -------------------------------------------------

$i = DB_DataObject::factory('Items');
$status = DB_DataObject::factory('Status');

// is the join in your database.links.ini file? If not use:
// $i->joinAdd( $status, "LEFT", 'status', 'fk_status' );

// it is in the .ini file so use:
$i->joinAdd( $status, "LEFT" );

$i->joinAdd( $status, "LEFT", 'minor_status', 'fk_minor_status' );

$i->selectAdd( 'item.name as name, status.name as status, minor_status.name as minor_status' );

// -------------------------------------------------

This assumes that Items has two foreign keys, both to status (fk_status and fk_minor_status)

I have used 'LEFT' joins because no all items will have a status (it is null) but we still want to list that item.

Don't forget: DB_DataObject::debugLevel(1); is your best friend ever, please invite him to the party and make sure he has a drink.

I hope this helps someone out. I think these type of JOINs are a basic part of SQL, so it's nice to see them included in DB_DataObject. I have logged this a documentation bug, so I hope this may be fixed one day...