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