UNIONを2つのコレクションに使用するにはどうすればよいですか?またはコレクションをマージしますか?(adminhtmlグリッドで使用)


7

まず、私がやろうとしていること:

まだ注文をしていない顧客と、顧客アカウントをまだ持っていないニューレター購読者のコレクションを入手してください。

mysqlにはFULL JOINおよびFULL OUTER JOINが存在しないため、基本的なSQLクエリは次のとおりです。

SELECT 
    `e`.`entity_id`, `e`.`group_id`, `e`.`email`, `salesOrder`.`entity_id` AS `order_id`, `salesRecurringProfile`.`profile_id`, `newsletterSubscriber`.`subscriber_status`, `newsletterSubscriber`.`subscriber_id`, `newsletterSubscriber`.`subscriber_email`, `newsletterSubscriber`.`customer_id` 
FROM 
    `customer_entity` AS `e`
LEFT JOIN 
    `sales_flat_order` AS `salesOrder` ON e.entity_id = salesOrder.customer_id AND salesOrder.status = 'processing'
LEFT JOIN 
    `sales_recurring_profile` AS `salesRecurringProfile` ON e.entity_id = salesRecurringProfile.customer_id AND salesRecurringProfile.state = 'active'
LEFT JOIN 
    `newsletter_subscriber` AS `newsletterSubscriber` ON e.entity_id = newsletterSubscriber.customer_id WHERE (salesOrder.entity_id IS NULL AND salesRecurringProfile.profile_id IS NULL)

UNION   

SELECT 
    `e`.`entity_id`, `e`.`group_id`, `e`.`email`, `salesOrder`.`entity_id` AS `order_id`, `salesRecurringProfile`.`profile_id`, `newsletterSubscriber`.`subscriber_status`, `newsletterSubscriber`.`subscriber_id`, `newsletterSubscriber`.`subscriber_email`, `newsletterSubscriber`.`customer_id` 
FROM 
    `customer_entity` AS `e`
LEFT JOIN 
    `sales_flat_order` AS `salesOrder` ON e.entity_id = salesOrder.customer_id AND salesOrder.status = 'processing'
LEFT JOIN 
    `sales_recurring_profile` AS `salesRecurringProfile` ON e.entity_id = salesRecurringProfile.customer_id AND salesRecurringProfile.state = 'active'
RIGHT JOIN 
    `newsletter_subscriber` AS `newsletterSubscriber` ON e.entity_id = newsletterSubscriber.customer_id WHERE (salesOrder.entity_id IS NULL AND salesRecurringProfile.profile_id IS NULL)

グリッドで使用するためにコレクションを使用してこれを転置しようとしています:

    $customersSubscribersLeftJoin = Mage::getResourceModel('customer/customer_collection');
    $customersSubscribersLeftJoin->getSelect()
        ->reset(Zend_Db_Select::COLUMNS)
        ->columns(array(
            'entity_id', 
            'group_id',
            'email'
        ))
        ->joinLeft(array('salesOrder' => $resource->getTableName('sales/order')), 'e.entity_id = salesOrder.customer_id AND salesOrder.status = \'' . Mage_Sales_Model_Order::STATE_PROCESSING .  '\'', array(
            'entity_id' => 'salesOrder.entity_id AS order_id'
        ))
        ->joinLeft(array('salesRecurringProfile' => $resource->getTableName('sales/recurring_profile')), 'e.entity_id = salesRecurringProfile.customer_id AND salesRecurringProfile.state = \'' . Mage_Sales_Model_Recurring_Profile::STATE_ACTIVE .  '\'', array(
            'profile_id'    => 'profile_id'
        ))
        ->joinLeft(array('newsletterSubscriber' => $resource->getTableName('newsletter/subscriber')), 'e.entity_id = newsletterSubscriber.customer_id', array(
            'subscriber_status' => 'subscriber_status',
            'subscriber_id'     => 'subscriber_id',
            'subscriber_email'  => 'subscriber_email',
            'customer_id'       => 'customer_id'
        ))
        ->reset(Zend_Db_Select::WHERE)
        ->where('salesOrder.entity_id IS NULL AND salesRecurringProfile.profile_id IS NULL');

    $customersSubscribersRightJoin = Mage::getResourceModel('customer/customer_collection');
    $customersSubscribersRightJoin->getSelect()
        ->reset(Zend_Db_Select::COLUMNS)
        ->columns(array(
            'entity_id', 
            'group_id',
            'email'
        ))
        ->joinLeft(array('salesOrder' => $resource->getTableName('sales/order')), 'e.entity_id = salesOrder.customer_id AND salesOrder.status = \'' . Mage_Sales_Model_Order::STATE_PROCESSING .  '\'', array(
            'entity_id' => 'salesOrder.entity_id AS order_id'
        ))
        ->joinLeft(array('salesRecurringProfile' => $resource->getTableName('sales/recurring_profile')), 'e.entity_id = salesRecurringProfile.customer_id AND salesRecurringProfile.state = \'' . Mage_Sales_Model_Recurring_Profile::STATE_ACTIVE .  '\'', array(
            'profile_id'    => 'profile_id'
        ))
        ->joinRight(array('newsletterSubscriber' => $resource->getTableName('newsletter/subscriber')), 'e.entity_id = newsletterSubscriber.customer_id', array(
            'subscriber_status' => 'subscriber_status',
            'subscriber_id'     => 'subscriber_id',
            'subscriber_email'  => 'subscriber_email',
            'customer_id'       => 'customer_id'
        ))
        ->reset(Zend_Db_Select::WHERE)
        ->where('salesOrder.entity_id IS NULL AND salesRecurringProfile.profile_id IS NULL');

では、これらの2つのコレクションのUNIONを作成する方法、または最初のコレクションのみを使用して1回の呼び出しでそれを作成する方法はありますか。

前もって感謝します


編集:

を使用して:

        $customersSubscribersLeftJoin->getSelect()
        ->union(
            array(
                $customersSubscribersRightJoin->getSelect()
            )
        );

与えられたクエリは:

   SELECT 
    `e`.`entity_id`, `e`.`group_id`, `e`.`email`, `salesOrder`.`entity_id` AS `order_id`, `salesRecurringProfile`.`profile_id`, `newsletterSubscriber`.`subscriber_status`, `newsletterSubscriber`.`subscriber_id`, `newsletterSubscriber`.`subscriber_email`, `newsletterSubscriber`.`customer_id`SELECT `e`.`entity_id`, `e`.`group_id`, `e`.`email`, `salesOrder`.`entity_id` AS `order_id`, `salesRecurringProfile`.`profile_id`, `newsletterSubscriber`.`subscriber_status`, `newsletterSubscriber`.`subscriber_id`, `newsletterSubscriber`.`subscriber_email`, `newsletterSubscriber`.`customer_id` 
FROM 
    `customer_entity` AS `e`
LEFT JOIN 
    `sales_flat_order` AS `salesOrder` ON e.entity_id = salesOrder.customer_id AND salesOrder.status = 'processing'
LEFT JOIN 
    `sales_recurring_profile` AS `salesRecurringProfile` ON e.entity_id = salesRecurringProfile.customer_id AND salesRecurringProfile.state = 'active'
RIGHT JOIN 
    `newsletter_subscriber` AS `newsletterSubscriber` ON e.entity_id = newsletterSubscriber.customer_id 
WHERE 
    (salesOrder.entity_id IS NULL AND salesRecurringProfile.profile_id IS NULL) 
FROM 
    `customer_entity` AS `e`
LEFT JOIN 
    `sales_flat_order` AS `salesOrder` ON e.entity_id = salesOrder.customer_id AND salesOrder.status = 'processing'
LEFT JOIN 
    `sales_recurring_profile` AS `salesRecurringProfile` ON e.entity_id = salesRecurringProfile.customer_id AND salesRecurringProfile.state = 'active'
LEFT JOIN 
    `newsletter_subscriber` AS `newsletterSubscriber` ON e.entity_id = newsletterSubscriber.customer_id 
WHERE 
    (salesOrder.entity_id IS NULL AND salesRecurringProfile.profile_id IS NULL)

2つのクエリの結合を作成することで、私たちが望んでいるのは、明らかにどのアイデアではありませんか?

回答:


3

2つのコレクションが正しく、2つのセットを結合するだけであると仮定すると、純粋に仮想的な観点から、次のことを試すことができます。

$customersSubscribersLeftJoin
    ->getSelect()
    ->union(
        array(
            $customersSubscribersLeftJoin->getSelect()
        )
    );

しかし、あなたは結果のコレクションであなたが困難を伴うだろうと思います。おそらく「このIDのアイテムはすでに存在します」のようなものになってしまいます。それは、それが機能することさえ想定しており、実際にはテストしていません。


こんにちは !回答していただきありがとうございます。私はこの方法でユニオンをテストしていますが、問題は、これによって行われる最終クエリに「UNION」を追加しないことです。2番目のクエリから選択を削除し、「FROM」と結合を連結します。本当におかしい
トーマス・セレス

詳細については、投稿を編集して、結合の結果のクエリを入力するだけです
Thomas Seres

1
それはそうZend_Db_Select::unionあなたが期待するかもしれない方法は動作しません、私はあなたがのインスタンスを必要とするだろう、正しいクエリを取得すると思うZend_Db_Selectし、次に渡すgetSelect()配列として両方のコレクションからを。Magentoに関してこれがどのように機能するかはわかりませんが、返された選択オブジェクトを、私の知る限りでは不可能であるコレクションの選択オブジェクトとして設定する必要があるようです。
Peter O'Callaghan

3

選択を複製してリセットする必要があります。

$customersLeftSelect = clone $customersSubscribersLeftJoin->getSelect();
$customersSubscribersLeftJoin
    ->getSelect()
    ->reset()
    ->union(
        array(
            $customersLeftSelect,
            $customersSubscribersRightJoin
        )
    );

これは私にとってそれがどのように機能したかです。


おかげで、うまくいきました。いくつか例を挙げます。この$ userCollection = clone $ collection-> getSelect();をご覧ください。UNION:$ myresult = $ userCollection-> reset()-> union(array($ adminCollection-> getSelect()-> __ toString()、$ collection-> getSelect()-> __ toString())); UNION ALL:$ myresult = $ userCollection-> reset()-> union(array($ adminCollection-> getSelect()-> __ toString()、$ collection-> getSelect()-> __ toString())、\ Magento \ Framework \ DB \ Select :: SQL_UNION_ALL);
Renga

1
$selectFoo = Mage::getResourceModel('model/foo')->getSelect();
$selectBar= Mage::getResourceModel('model/bar')->getSelect();

$mergedFooBar = $selectFoo->union(array($selectBar));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.