Kiri gabung dengan tabel pada kueri koleksi

27

Saya melakukan yang berikut untuk mendapatkan beberapa pesanan dari sistem untuk ekspor:

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

Saya perlu menambahkan sesuatu yang tidak diekspor jika pesanan entity_idada di tabel khusus yang saya miliki. Jika saya menggunakan SQL, saya akan melakukan:

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

Tetapi saya tidak yakin bagaimana memodifikasi kueri koleksi untuk melakukan hal serupa.

Catatan: Saya sudah mencoba

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

tapi ini mengubahnya jadi permintaan dan saya ingin koleksi penjualan / pesanan dikembalikan.

Saya merasa saya kehilangan sesuatu yang sederhana ...

EDIT

Oke, saya sudah mencoba ini:

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

Ketika saya menggema (string)$orders->getSelect()itu mengembalikan permintaan saya harapkan dan tidak mengembalikan hasil ketika saya menjalankannya. $ordersNamun, masih mengandung item. Saya pikir gabung ini dimaksudkan untuk memodifikasi koleksi pada saat ini?

webnoob
sumber

Jawaban:

53

Untuk mengubah kueri yang bisa Anda lakukan

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

Tetapi untuk bergabung dengan sebuah tabel, Anda bisa menggunakannya $collection->joinTable()

joinTablehanya ada di Mage_Eav_Model_Entity_Collection, ini berarti: produk, kategori, pesanan, faktur, creditmemo, pengiriman, pelanggan. (Terima kasih @Fra atas komentarnya)

joinTable ()

Tetapi koleksi magento memiliki metode joinTable()yang saya butuhkan 45 menit untuk mencari tahu bagaimana menggunakannya. Untuk menghindari ini untuk Anda, saya membagikannya.

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

Parameternya adalah:

public function joinTable($table, $bind, $fields = null, $cond = null, $joinType = 'inner')
  1. Tabel mudah, ini adalah namespace/entityformat magento , yang Anda gunakan dalam konfigurasi, model sumber daya, dan koleksi Anda. Anda dapat menggunakan larik formatarray('alias' => 'namespace/entity')
  2. Bind berarti, pernyataan AKTIF dalam SQL Anda. Ini adalah bagian tersulit dan saya akan menjelaskannya secara terperinci nanti. Penting untuk memiliki tabel datar Anda SEBELUM dan tabel EAV Anda SETELAH tanda yang sama. Jangan gunakan main_table.sebelum atribut. Magento akan melakukan ini untukmu. Lebih lanjut tentang ini nanti.
  3. Fields adalah sebuah array . Jika Anda menggunakan string sebagai gantinya, Anda mendapatkan ini: 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. Anda dapat menggunakan larik format array('field1', 'field2', '...')atauarray('alias' => 'field1', '...')
  4. Syaratnya adalah ** DIMANA Kondisi ON ** dalam SQL.
  5. joinType. Saya harap kamu tahu apa itu. Tetapi Anda hanya memiliki pilihan antara KIRI dan INNER .app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php:793

Lebih banyak tentang topik ini

Fabian Blechschmidt
sumber
1
Terima kasih atas info hebatnya. Berdasarkan poin pertama Anda, bukankah seharusnya $orders->getSelect() ->joinLeft(array("t1" => $myTable), "main_table.entity_id = t1.entity_id", array("admin_field_id" => "t1.id")) ->where("t1.id is null")mengecualikan item dari daftar saya saat ini?
webnoob
Saya pikir Anda mengedit koleksi setelah memuat. cukup kaitkan ke skrip Anda dengan xdebug dan periksa bendera isLoaded di dalam model
Fabian Blechschmidt
2
layak untuk disebutkan bahwa metode joinTable hanya tersedia untuk Mage_Eav_Model_Entity_Collection
Fra
1

Saya menemukan alasan untuk ini.

Saya ingin hitungan nilai sebelum saya menerapkan gabung kiri jadi saya menambahkan

$totalOrderCount = count($orders);

Namun ini menyebabkan koleksi memuat yang pada gilirannya berarti mengabaikan bergabung kiri yang saya lakukan selanjutnya. Saat debugging, melihat var _isCollectionLoadedadalah tip yang bagus dari Fabian.

Saya sekarang melakukan ini sebagai gantinya untuk mendapatkan hitungan koleksi:

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

Ini memungkinkan saya untuk menghitung hasil tanpa memuat $orderskoleksi.

Catatan: Tolong terapkan upvotes apa pun untuk posting Fabians di atas saat dia membimbing saya dalam hal ini tetapi saya merasa solusinya menjamin itu jawaban sendiri.

webnoob
sumber