Magento filter order collection by product sku - magento

I'm using magento 1.7 and I need to get all orders from certain increment_id containing at least one item matching a sku.
Here's what I have:
$orderCollection = Mage::getModel('sales/order')->getCollection()
->addFieldToFilter('status',
array(
'nin' => array(
'new',
'pending',
'pending_payment',
'holded',
'canceled')
))
->addFieldToFilter('increment_id', array('gteq' => $last_order));
If I add a line with:
$orderCollection->addFieldToFilter('sku', $findSku);
I will get a PHP fatal error since 'sku' is not a field. I've tried addAttributeToFilter() and it won't work either.
I know I need to build a join with another table, but I don't know how joins are made in Magento and I don't know which table I should join to.
Any help will be greatly appreciated.

SKUs are placed in order item table not in orders.
Your final query must look like this one:
SELECT o.increment_id
FROM sales_flat_order_item oi
INNER JOIN sales_flat_order o ON o.entity_id = oi.order_id
WHERE product_id=XXX
ORDER BY o.increment_id DESC;
This query can be done using nearly such syntax:
$orderItem = Mage::getModel('sales/order_item')->getCollection();
$orderItem
->getSelect()
->joinInner(array('order' => Mage::getSingleton('core/resource')->getTableName('sales/order')), 'order.entity_id = main_table.order_id' )
->where('product_id=?', $productId)
->order('main_table.order_id DESC');

Related

Is there a way to rewrite this raw SQL query with Laravel Query Builder

I have two tables:
products
id | code | supplier_id |...
company_product
id | retail_price | copmany_id |...
There are multiple online shops from where I'm pulling the products via their API's which I store locally. It is pretty much used to compare their prices, unit stock, and so on which can be done via product code which is the same across all shops.
I'm fetching all products only once and updating them a couple of times daily. Other companies using this, let's say "platform", have different prices for products based on their contracts which are kept in the second table.
The thing I'm trying to achieve is to list all products but only the cheapest version of the product for that product code.
I am able to achieve it with the following query.
$products = DB::select(DB::raw(
"select p.*, t.price_min
from (select MAX(p.id) as id, p.code, MIN(cp.retail_price) as price_min
from products as p
left join company_product as cp on cp.product_id = p.id
group by p.code) as t
left join products as p on p.id = t.id"
));
Which gives me the result I want. However, I have lots of filters, sorts, relations, and pagination to add on top of this, which is the reason why I'm trying to rewrite it.
Every suggestion is much appreciated.
First of all, the raw MySQL query you probably want here is just an inner join:
SELECT p.*, t.price_min
FROM products p
INNER JOIN
(
SELECT p.code, MAX(p.id) AS max_id, MIN(cp.retail_price) AS price_min
FROM products p
INNER JOIN company_product cp ON cp.product_id = p.id
GROUP BY p.code
) t
ON p.id = t.max_id
As for the Laravel code, we can try creating the subquery in a separate variable, and then join to it:
$subquery = DB::table('products AS p')
->select([
'p.code',
DB::raw('MAX(p.id) AS max_id, MIN(cp.retail_price) AS price_min')])
->join('company_product AS cp', 'cp.product_id', '=', 'p.id')
->groupBy('p.code');
$query = DB::table('products AS p')
->select('p.*', 't.price_min')
->innerJoinSub($subquery, 't', function($join) {
$join->on('p.id', '=', 't.max_id');
})
->get();

Refer table filed that belong to multiple tables

I am trying to get all the products that have sold the most within a window of time. I am using the following query
$productCollection = Mage::getResourceModel('reports/product_collection')
->addOrderedQty()
->addAttributeToSelect('*')
->setStoreId($storeId)
->addStoreFilter($storeId)
->setOrder('ordered_qty', 'desc')
->setOrder('created_at', 'desc');
However created_at is a field in more than one table. How to correctly refer to the field from the table I intend to. I would also like to filter using the field from the intended table.
The query will look like this
SELECT ...... FROM `sales_flat_order_item` AS `order_items` INNER JOIN `sales_flat_order` AS `order` ON `order`.entity_id = order_items.order_id AND `order`.state <> 'canceled' LEFT JOIN `catalog_product_entity` AS `e` .....
So you have the tables aliases
order_items, order , and e
So you can add order like this
$productCollection->getSelect()->order('order_items.created_at' . ' ' . 'DESC');

Magento: Query Database for products with no assigned categories

I'm really new to Magento and I'm looking to find a way to get a list of all the products in the catalog which are not assigned to any categories. Can anyone offer any help as to how this can be achieved?
Many thanks.
Select entity_id from catalog_product_entity where entity_id not in (select distinct product_id from catalog_category_product);
This will give you all product entity id not belonging to any category.
You can get product collection by using following code :
$product = Mage::getModel('catalog/product');
$productCollection = $product->getCollection()
->addAttributeToSelect('*');
foreach ( $productCollection as $_product ) {
echo $_product->getName().'<br/>';
}
But for your requirement you can get idea from following links,may be its help you.
How do I get product category information using collections in Magento

Magento Load Collection Using Order By

My query is generating from magento collection is
$userModel = Mage::getSingleton('user/user')->getCollection()->addFieldToFilter('user_id', array('in' => array($User_Id)));
SELECT `main_table`.user_name FROM `user_table` AS `main_table` WHERE (user_id IN('1', '3', '2'));
I want to use this query:
SELECT `main_table`.user_name FROM `user_table` AS `main_table` WHERE (user_id IN('1', '3', '2')) ORDER BY FIELD(user_id , 1,3,2);
So that it will display the user name in the same order as ID's are input.
i.e. "1,3,2"
Which method is used in Magento to load collection using ORDER BY?
Thanks in advance!
You can get Zend_Db_Select from Collection and then add order to Zend_Db_Select like this question:
Zend DB Select : ORDER BY FIELD('id',some_array) - how?

Magento Get Product SELECTED ATTRIBUTE only?

Hi i'm working on an external application thats shows all the ordered items on a magento store.
The query that display the ordered product attribute is this :
select group_concat(distinct(b.value) separator '<br/>') from catalog_product_entity_varchar a , eav_attribute_option_value b , eav_attribute c
where a.value = b.option_id
and c.attribute_id = a.attribute_id
and c.is_user_defined = 1
and a.entity_id = PRODUCT_ID
This is for the attributes with type VARCHAR , i use the same query to get attributes of int and text. I just change the table name from catalog_product_entity_varchar to catalog_product_entity_int and catalog_product_entity_text.
The problem that i have is that i GET all the product attributes , manufacturer , supplier... and due to the fact that we got many stores i dont want to retrieve all the additional attributes with an additional sql where clause!
Any solution to get only selected attributes?
The below will grab the collection in PHP. You just need to change the Attribute that you select on. By adding the ->addOrderedQty, it allows the ability to get the ordered qty. Now I understand that you are using an external application. The reason that I post this is that you can load the Mage.php into your application and use this directly or you can just run this once and watch for the query in your database and then use that query to accomplish what you are looking to.
$visibility = array(
Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
);
$_productCollection = Mage::getResourceModel('reports/product_collection')
->addAttributeToSelect('*')
->addOrderedQty()
->addAttributeToFilter('visibility', $visibility)
->setOrder('ordered_qty', 'desc');

Resources