Magento – Get number of orders per customer

collection;customermagento-1sales-order

I've to filter from, to and multiple customer in sales order.

I don't have customer id's, so first I'm taking them using following code:

$customer_ids = array();
$orders = Mage::getModel('sales/order')->getCollection()
    ->addAttributeToFilter('created_at', array('from' => $fromDate, 'to' => $toDate));

foreach ($orders as $order) {
    $customer_id = $order->getCustomerId();
    array_push($customer_ids, $order->getCustomerId());
}

foreach ($customer_ids as $customer_id) {
    $orders = Mage::getModel('sales/order')->getCollection()
        ->addAttributeToFilter('created_at', array('from' => $fromDate, 'to' => $toDate))
        ->addFieldToFilter('customer_id', $customer_id);
    $_orderCnt = $orders->count(); //orders count
    echo "Customer ID : " . $customer_id . " Order Count : ". $_orderCnt. "<br>";
}

Above code is used to find how many orders have been placed by customers during selected time period.

I've used following code to not load collection in foreach but it's not working.

foreach ($customer_ids as $customer_id) {
    $temp = $orders;
    $temp->addFieldToFilter('customer_id',$customer_id);
    $_orderCnt = $temp->count(); //orders count
    echo "Customer ID : " . $customer_id . " Order Count : ". $_orderCnt. "<br>";
    unset($temp);
}

Can anyone suggest me how I can optimize the code without loading collection everytime?

Best Answer

Please try this:

$orders = Mage::getModel('sales/order')->getCollection()
    ->addAttributeToFilter('created_at', array('from' => $fromDate, 'to' => $toDate));
$array = array_count_values($orders->getColumnValues('customer_id'));

foreach ($array as $customerId => $orderCount) {
    echo "Customer ID : " . $customerId . " Order Count : ". $orderCount. "<br>";
}

Explanation:

This stores customer_id for all orders in an array ...

$orders->getColumnValues('customer_id')

... and array_count_values sums same array values and stores it as array again.

Edit:

If you have orders, where customer_id is null then array_count_values gives an error (Warning: array_count_values(): Can only count STRING and INTEGER values!).

So you have to replace null first:

$array = array_count_values(array_map(function($v) {
    return (is_null($v)) ? "?" : $v;
}, $orders->getColumnValues('customer_id')));
Related Topic