コレクションクエリでテーブルを左結合する


27

エクスポートのためにシステムからいくつかの注文を取得するために、次のことを行っています。

$orders = Mage::getModel('sales/order')->getCollection()
    ->addFieldToFilter('status', $statusToExport)
    ->addFieldToFilter('store_id', $this->processingStoreId)
    ->addFieldToFilter('updated_at', array('gteq' => date('Y-m-d H:i:s', $lastSyncTime)));

注文がカスタムテーブルにある場合、エクスポートしない場所に何かを追加する必要がありentity_idます。SQLを使用していた場合、次のようにします。

left join myTable as mt on main_table.entity_id = mt.entity_id
where mt.entity_id is null

ただし、コレクションクエリを変更して同様のことを行う方法はわかりません。

注:試しました

$orders = $orders->getSelect()
    ->joinLeft(
        array("t1" => $myTable),
        "main_table.entity_id = t1.entity_id",
        array("admin_field_id" => "t1.id")
    )
    ->where("t1.id is null")

ただし、これによりクエリが変更されるため、販売/注文のコレクションを返す必要があります。

シンプルなものが足りないと感じています...

編集

OK、私はこれを試しました:

$orders->getSelect()
    ->joinLeft(
        array("t1" => $myTable),
        "main_table.entity_id = t1.entity_id",
        array("admin_field_id" => "t1.id")
    )
    ->where("t1.id is null");

エコー(string)$orders->getSelect()すると、予想されるクエリが返され、実行しても結果は返されません。$ordersただし、アイテムはまだ含まれています。この結合は、この時点でコレクションを変更するためのものだと思いましたか?

回答:


53

できるクエリを変更するには

$collection->getSelect()->doWhateverYouWantWithSelectObject();
foreach($collection as $order) {} // order collection

しかし、テーブルに参加するには、単に使用することができます $collection->joinTable()

joinTableMage_Eav_Model_Entity_Collectionにのみ存在します。これは、製品、カテゴリ、注文、請求書、クレジットメモ、配送、顧客を意味します。(コメントをありがとう@Fra)

joinTable()

しかし、magentoコレクションには、その使用方法をjoinTable()45分かけて解決する方法がありました。これを避けるために、共有します。

$productCollection->joinTable(
    array('bonus' => 'mycompany/bonus'), 'product_id=entity_id',
    array('bonus_id' => 'bonus_id')
);

パラメーターは次のとおりです。

public function joinTable($table, $bind, $fields = null, $cond = null, $joinType = 'inner')
  1. テーブルは簡単です。これは、namespace/entity設定、リソースモデル、およびコレクションで使用するmagento 形式です。次の形式の配列を使用できますarray('alias' => 'namespace/entity')
  2. バインドとは、SQLのONステートメントです。これが最も難しい部分でした。後で詳しく説明します。平表の前にフラットテーブルを持ち、等号の後にEAVテーブルを持つことが重要です。main_table.属性の前に使用しないでください。Magentoがこれを行います。これについては後で詳しく説明します。
  3. Fieldsは配列です。代わりに文字列を使用すると、次のようになりますWarning: Invalid argument supplied for foreach() in /var/www/magento-1.6.2.0/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php on line 775。次の形式の配列を使用するarray('field1', 'field2', '...')か、array('alias' => 'field1', '...')
  4. 条件は** どこ SQLのON条件**。
  5. joinType。あなたはそれが何であるか知っていることを願っています。ただし、LEFTとINNERのどちらかしか選択できませんapp/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php:793

このトピックの詳細


1
その素晴らしい情報をありがとう。最初のポイントに基づいて$orders->getSelect() ->joinLeft(array("t1" => $myTable), "main_table.entity_id = t1.entity_id", array("admin_field_id" => "t1.id")) ->where("t1.id is null")、現在のリストからアイテムを除外すべきではありませんか?
webnoob

ロード後にコレクションを編集すると思います。xdebugを使用してスクリプトをフックし、モデル内のisLoadedフラグを確認してください
Fabian Blechschmidt

2
joinTableメソッドは、Mage_Eav_Model_Entity_Collectionでのみ使用可能です
Fra

1

その理由を見つけました。

左結合を適用するに値のカウントが必要だったため、追加しました

$totalOrderCount = count($orders);

ただし、これによりコレクションがロードされ、これはさらに行っていた左結合を無視することを意味しました。デバッグ中に、var _isCollectionLoadedを確認することはFabianによる良いヒントでした。

コレクションの数を取得するために、代わりにこれを実行しています:

$countOrdersObjs = clone $orders;
$totalOrderCount = count($countOrdersObjs);
unset($countOrdersObjs);

これにより、$ordersコレクションをロードせずに結果をカウントできます。

注:上記のファビアンにアップボットを適用してください。彼はこれについて私を指導しましたが、解決策はそれ自身の答えを保証すると感じました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.