Làm cách nào tôi có thể sử dụng UNION cho 2 bộ sưu tập? Hoặc hợp nhất các bộ sưu tập? (để sử dụng trong lưới adminhtml)


7

Trước hết, những gì tôi đang cố gắng làm:

Nhận một bộ sưu tập với những khách hàng chưa có đơn đặt hàng và những người đăng ký mới đăng ký không có tài khoản khách hàng.

Trong mysql FULL THAM GIA và FULL OUTER THAM GIA không tồn tại nên truy vấn sql cơ bản của tôi là:

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)

Tôi đang cố gắng thay đổi điều này bằng cách sử dụng các bộ sưu tập để sử dụng nó với lưới:

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

Vậy làm thế nào tôi có thể tạo một UNION của 2 bộ sưu tập đó, hoặc thực hiện nó trong một cuộc gọi duy nhất chỉ với bộ sưu tập đầu tiên?

Cảm ơn bạn trước


BIÊN TẬP :

Bằng cách sử dụng :

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

Truy vấn đã cho là:

   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)

Đó rõ ràng không phải là những gì chúng ta muốn bằng cách làm cho sự kết hợp của hai truy vấn, bất kỳ ý tưởng?

Câu trả lời:


3

Giả sử hai bộ sưu tập là chính xác và tất cả những gì bạn cần làm là tham gia hai bộ, từ quan điểm hoàn toàn giả thuyết mà bạn có thể thử:

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

Tôi nghi ngờ tuy nhiên bạn sẽ gặp khó khăn với bộ sưu tập kết quả. Bạn có thể sẽ kết thúc với một cái gì đó như "mục có id này đã tồn tại" và giả sử nó thậm chí còn hoạt động, điều mà tôi chưa thực sự thử nghiệm.


Chào ! Cảm ơn bạn đã dành thời gian để trả lời! Tôi kiểm tra cách này để thực hiện liên minh, vấn đề là truy vấn cuối cùng được thực hiện bởi điều này, không thêm "UNION". Nó xóa lựa chọn từ truy vấn thứ hai và nối "TỪ" và các phép nối! Thực sự kỳ lạ
Thomas Seres 13/12/13

Để biết thêm thông tin, tôi chỉ cần chỉnh sửa bài đăng của mình và đặt kết quả truy vấn của liên minh
Thomas Seres

1
Có vẻ như Zend_Db_Select::unionnó không hoạt động như bạn mong đợi, tôi nghĩ để có được truy vấn chính xác mà bạn cần một thể hiện Zend_Db_Selectvà sau đó chuyển getSelect()từ cả hai bộ sưu tập thành một mảng. Tuy nhiên, tôi không chắc nó sẽ hoạt động như thế nào đối với Magento, vì dường như bạn cần đặt đối tượng chọn trả về làm đối tượng được chọn trên bộ sưu tập mà theo hiểu biết của tôi là không thể.
Peter O'Callaghan

3

Bạn cần sao chép và thiết lập lại lựa chọn của bạn.

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

Đây là cách nó làm việc cho tôi.


Cảm ơn, nó làm việc cho tôi. Tôi cung cấp cho bạn một số ví dụ, vui lòng xem $ userCollection = clone $ sưu tập-> getSelect (); UNION: $ myresult = $ userCollection-> reset () -> union (mảng ($ adminCollection-> getSelect () -> __ toString (), $ sưu tập-> getSelect () -> __ toString ())); UNION ALL: $ myresult = $ userCollection-> reset () -> union (mảng ($ adminCollection-> getSelect () -> __ toString (), $ sưu tập-> getSelect () -> __ toString ()), \ Magento \ Framework \ DB \ Chọn :: SQL_UNION_ALL);
Renga

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

$mergedFooBar = $selectFoo->union(array($selectBar));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.