Слева присоединиться к таблице в запросе коллекции


Я делаю следующее, чтобы получить некоторые заказы из системы для экспорта:

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

Но это меняет его, так что это запрос, и мне нужна коллекция продаж/заказов возвращенный.

Я чувствую, что упускаю что-то простое...

РЕДАКТИРОВАТЬ

Хорошо, я попробовал это:

$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 однако все еще содержит элементы. Я думал, что это объединение предназначено для изменения коллекции на данном этапе?

Author: sv3n, 2013-11-04

2 answers

Чтобы изменить запрос, вы можете сделать

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

Но чтобы присоединиться к таблице, вы можете просто использовать $collection->joinTable()

joinTable существует только в Mage_Eav_Model_Entity_Collection, это означает: продукты, категории, заказы, счета-фактуры, информация о кредите, доставка, клиенты. (Спасибо @Fra за комментарий)

Объединяемый()

Но в коллекциях 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. Таблица проста, это формат magento namespace/entity, который вы используете в своей конфигурации, моделях ресурсов и коллекции. Вы можете использовать массив формата array('alias' => 'namespace/entity')
  2. Привязка означает оператор ON в вашем SQL. Это была самая трудная часть, и я подробно объясню это позже. Важно, чтобы ваша плоская таблица была ДО, а ваша таблица EAV - ПОСЛЕ знака равенства. Не используйте main_table. перед атрибутом. Magento сделает это за вас. Подробнее об этом позже.
  3. Поля - это массив . Если вместо этого вы используете строку, вы получите следующее: 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.
  5. Совместный тип. Я надеюсь, вы знаете, что это такое. Но у вас есть только выбор между ЛЕВЫМ и ВНУТРЕННИМ. app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php:793

Подробнее на эту тему

 54
Author: Fabian Blechschmidt, 2017-07-16 09:19:56

Я нашел причину этого.

Я хотел подсчитать значения до Я применил левое соединение, поэтому я добавил

$totalOrderCount = count($orders);

Однако это привело к загрузке коллекции, что, в свою очередь, означало, что она игнорировала левое соединение, которое я делал дальше. Во время отладки просмотр var _isCollectionLoaded был хорошим советом Фабиана.

Теперь я делаю это вместо того, чтобы получить количество коллекции:

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

Это позволяет мне подсчитывать результаты без загрузки $orders коллекция.

Примечание: Пожалуйста, применяйте любые комментарии к сообщению Fabians выше, поскольку он руководил мной в этом, но я чувствовал, что решение оправдывает его собственный ответ.

 1
Author: webnoob, 2013-11-06 09:39:31