컬렉션 쿼리에서 테이블을 왼쪽 조인


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

그러나 이것은 변경되어 쿼리이므로 판매 / 주문 컬렉션을 반환하고 싶습니다.

나는 간단한 것을 놓치고 있다고 생각합니다 ...

편집하다

좋아, 나는 이것을 시도했다 :

$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에만 존재하며 이는 제품, 카테고리, 주문, 송장, 대변 메모, 운송, 고객을 의미합니다. (댓글을 보내 주셔서 감사합니다)

joinTable ()

그러나 마 젠토 컬렉션에는 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구성, 자원 모델 및 콜렉션에서 사용 하는 마 젠토 형식입니다. 형식의 배열을 사용할 수 있습니다array('alias' => 'namespace/entity')
  2. 바인드는 SQL의 ON 문을 의미합니다. 이것이 가장 어려운 부분이며 나중에 자세히 설명하겠습니다. 등호 뒤에 평평한 테이블과 EAV 테이블을 두는 것이 중요합니다. main_table.속성 앞에 사용하지 마십시오 . 마 젠토가 당신을 위해 이것을 할 것입니다. 이것에 대해서는 나중에 더 설명하겠습니다.
  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에서 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 표시 플래그 확인
파비안 Blechschmidt

2
joinTable 메소드는 Mage_Eav_Model_Entity_Collection에만 사용 가능
Fra

1

나는 그 이유를 찾았다.

왼쪽 조인을 적용 하기 전에 많은 값을 원했기 때문에 추가했습니다.

$totalOrderCount = count($orders);

그러나 컬렉션이로드되어 결과적으로 왼쪽 조인을 무시했습니다. 디버깅하는 동안 Fab을 보면 var _isCollectionLoaded를 보는 것이 좋은 팁이었습니다.

컬렉션의 수를 얻기 위해 대신이 작업을 수행하고 있습니다.

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

이렇게하면 $orders컬렉션 을로드하지 않고도 결과를 계산할 수 있습니다.

참고 : 위의 게시물을 Fabians에 안내하면 위의 게시물을 위의 게시물에 적용하십시오. 그러나 해결책이 자체 답변이 필요하다고 느꼈습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.