For a product page I'd like to show 1 random product from each of the 3 preselected categories. The final layout would be 3 products next to each other (1 from each category). Now I have read several topics about the random product issue, none of them however address the issue of having several single products from different categories.

I started by creating the code that would pick a random product from a specific category:

$catid = '338';
$category = new Mage_Catalog_Model_Category();
$collection = $category->getProductCollection();
$numProducts = 1;
$collection->setPage(1, $numProducts)->load();

<?php foreach($collection as $product): ?>

<?php $product = Mage::getModel('catalog/product')->load($product->getId());
  echo $product->getName();
  echo $product->getShortDescription(); ?>
<?php endforeach; ?>
<?php endif; ?>

This works just fine. What would be the next step to get 1 product from the other 2 categories (say id 339 & 340)?


An efficient solution for big catalogs is to first load all product ids from the three categories, then pick one randomly from each of them and finally load these products by ID.

This might seem counter-intuitive, but ORDER BY RAND() has serious performance issues, the larger the table is and it gets worse with joining all the EAV tables. See also: show random products from a category


$categories = Mage::getResourceModel('catalog/category_collection')
    ->addFieldToFilter('entity_id', array('in' => [338, 339, 340]));
$productIds = array();
foreach ($categories as $category) {
    $candidateIds = $category->getProductCollection()->getAllIds();
    $productIds[] = $candidateIds[array_rand($candidateIds)];

$products = Mage::getResourceModel('catalog/product_collection')

Now $products is the product collection with three random products and all data that you need to display it in a product list template.

  • Thanks for this, I do seem to get a parse error on the first line I'm not sure how to solve...
    – Badger
    Sep 7 '15 at 15:27
  • Sorry, I updated the code, it should work now Sep 7 '15 at 15:29
$category_ids = array(338,339,340);
$productids_from_each_category = array();

// loading category and one product from resp category and storing id in the variable called $productids_from_each_category
foreach($category_ids as $category_id){
    $_productCollection = Mage::getModel('catalog/category')->load($category_id)
                            ->addAttributeToFilter('status', 1)
                            ->addAttributeToFilter('visibility', 4);

    $collection = $_productCollection->getFirstItem();

        $productids_from_each_category[] = $collection->getId();

// loading products collection
$product_collection = Mage::getModel('catalog/product')
                ->addAttributeToFilter('entity_id', array('in' => $productids_from_each_category))

echo "<pre>"; print_r($product_collection->getData());
  • The only thing i would add to this is a check before adding it to the productids_from_each_category just to make sure there is actually a result.
    – Smartie
    Sep 7 '15 at 14:57
  • yes i am updating the answer now Sep 7 '15 at 14:59
  • done updated my answer Sep 7 '15 at 14:59
  • 1
    Although this might work it's an extremely heavy script and should in no way be used on a production shop. We're talking about multiple joining queries that are used to retrieve 3 products
    – Sander Mangel
    Sep 7 '15 at 15:07
  • 1
    Yes, and also adding the rand() means the query cannot be cached
    – Smartie
    Sep 7 '15 at 15:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.