Links Join einer Tabelle in einer Auflistung Abfrage

27

Ich tue Folgendes, um einige Bestellungen für den Export aus dem System zu bekommen:

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

Ich muss etwas hinzufügen, das nicht exportiert werden kann, wenn sich die Reihenfolge entity_idin einer benutzerdefinierten Tabelle befindet, die ich habe. Wenn ich SQL verwenden würde, würde ich Folgendes tun:

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

Ich bin mir jedoch nicht sicher, wie ich die Sammlungsabfrage ändern soll, um etwas Ähnliches zu tun.

Hinweis: Ich habe es versucht

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

Dies ändert sich jedoch, sodass es sich um eine Abfrage handelt, und ich möchte, dass der Verkaufs- / Auftragsbestand zurückgegeben wird.

Mir fehlt etwas Einfaches ...

BEARBEITEN

Ok, ich habe es versucht:

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

Wenn ich ein Echo (string)$orders->getSelect()erhalte, wird die erwartete Abfrage zurückgegeben. Wenn ich sie ausführe, werden keine Ergebnisse zurückgegeben. $ordersEnthält jedoch noch Elemente. Ich dachte, dass dieser Join die Sammlung zu diesem Zeitpunkt ändern sollte?

webnoob
quelle

Antworten:

53

Um die Abfrage zu ändern, können Sie tun

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

Aber um sich einem Tisch anzuschließen, können Sie einfach verwenden $collection->joinTable()

joinTableExistiert nur bei Mage_Eav_Model_Entity_Collection. Dies bedeutet: Produkte, Kategorien, Bestellungen, Rechnungen, Gutschriften, Versand, Kunden. (Danke @Fra für den Kommentar)

joinTable ()

Aber Magento-Sammlungen haben eine Methode joinTable(), bei der ich 45 Minuten gebraucht habe, um herauszufinden, wie sie verwendet werden. Um dies für Sie zu vermeiden, teile ich es.

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

Die Parameter sind:

public function joinTable($table, $bind, $fields = null, $cond = null, $joinType = 'inner')
  1. Tabelle ist einfach, es ist das Magento- namespace/entityFormat, das Sie in Ihrer Konfiguration, Ressourcenmodellen und der Sammlung verwenden. Sie können ein Array des Formats verwendenarray('alias' => 'namespace/entity')
  2. Bind bedeutet, die ON-Anweisung in Ihrem SQL. Dies war der schwierigste Teil und ich werde es später im Detail erklären. Es ist wichtig, dass Sie Ihren flachen Tisch VOR und Ihren EAV-Tisch NACH dem Gleichheitszeichen haben. Nicht main_table.vor dem Attribut verwenden. Magento erledigt das für Sie. Dazu später mehr.
  3. Fields ist ein Array . Wenn Sie eine Zeichenfolge stattdessen verwenden, erhalten Sie diese: 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. Sie können ein Array des Formats array('field1', 'field2', '...')oder verwendenarray('alias' => 'field1', '...')
  4. Voraussetzung ist ein ** WOHER EIN-Bedingung ** in der SQL.
  5. joinType. Ich hoffe du weißt was es ist. Sie haben aber nur die Wahl zwischen LINKS und INNEN .app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php:793

Mehr zu diesem Thema

Fabian Blechschmidt
quelle
1
Danke für die tolle Info. Sollten Sie $orders->getSelect() ->joinLeft(array("t1" => $myTable), "main_table.entity_id = t1.entity_id", array("admin_field_id" => "t1.id")) ->where("t1.id is null")die Artikel, basierend auf Ihrem ersten Punkt, nicht von meiner aktuellen Liste ausschließen?
Webnoob
Ich denke, Sie bearbeiten die Sammlung nach dem Laden. Hängen Sie sich einfach mit xdebug in Ihr Skript ein und überprüfen Sie die isLoaded-Flagge im Modell
Fabian Blechschmidt,
2
Erwähnenswert ist, dass die joinTable-Methode nur für Mage_Eav_Model_Entity_Collection
Fra
1

Ich habe den Grund dafür gefunden.

Ich wollte eine Anzahl von Werten, bevor ich die linke Verknüpfung anwendete, also fügte ich hinzu

$totalOrderCount = count($orders);

Dies führte jedoch dazu, dass die Sammlung geladen wurde, was wiederum bedeutete, dass der Link-Join, den ich weiter machte, ignoriert wurde. Beim Debuggen _isCollectionLoadedwar es ein guter Tipp von Fabian , sich den var anzuschauen.

Ich mache dies jetzt stattdessen, um die Zählung der Sammlung zu erhalten:

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

Auf diese Weise kann ich die Ergebnisse zählen, ohne die $ordersSammlung zu laden .

Hinweis: Bitte wende alle Upvotes auf Fabians Beitrag an, da er mich dazu geführt hat, aber ich dachte, dass die Lösung eine eigene Antwort rechtfertigt.

webnoob
quelle