I need a list of ACTIVE products from the magento database with the following information.
If there are additional information that is fine, but the following information need to be there.
SKU:
PRODUCT NAME:
PRODUCT CATEGORY:
SHORT DESCRIPTION:
LONG DESCRIPTION:
WEIGHT:
What is the way to write a query for this. I just need to get the data. No php, just sql query.(Db structure is bit complex)
try that, it works to get the product data: (status = 2 = product disabled, status = 1 = product enabled)
SELECT `e`.*, IF(_table_status.value_id > 0, _table_status.value, _table_status_default.value) AS `status
FROM `mage_catalog_product_entity` AS `e`
INNER JOIN `mage_catalog_product_entity_int` AS `_table_status_default`
ON (`_table_status_default`.`entity_id` = `e`.`entity_id`)
AND (`_table_status_default`.`attribute_id` = '80')
AND `_table_status_default`.`store_id` = 0
LEFT JOIN `mage_catalog_product_entity_int` AS `_table_status`
ON (`_table_status`.`entity_id` = `e`.`entity_id`)
AND (`_table_status`.`attribute_id` = (SELECT attribute_id FROM mage_eav_attribute WHERE attribute_code = 'status' AND entity_type_id = 4))
AND (`_table_status`.`store_id` = '1')
WHERE (IF(_table_status.value_id > 0, _table_status.value, _table_status_default.value) = '2')
For the category you will need some extra work. I get this sql query by doing the following in PHP and the Magento collection:
/* #var $productCollection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */
$productCollection = Mage::getModel('catalog/product')->getCollection();
$productCollection->addFieldToFilter('status', array('eq' => '2'))->load(true);
Related
I have a situation where two tables should be joined with multiple columns with or condition. Here, I have a sample of sql query but i was not able to convert it into linq query.
select cm.* from Customer cm
inner join #temp tmp
on cm.CustomerCode = tmp.NewNLKNo or cm.OldAcNo = tmp.OldNLKNo
This is how i have write linq query
await (from cm in Context.CustomerMaster
join li in list.PortalCustomerDetailViewModel
on new { OldNLKNo = cm.OldAcNo, NewNLKNo = cm.CustomerCode } equals new { OldNLKNo = li.OldNLKNo, NewNLKNo = li.NewNLKNo }
select new CustomerInfoViewModel
{
CustomerId = cm.Id,
CustomerCode = cm.CustomerCode,
CustomerFullName = cm.CustomerFullName,
OldCustomerCode = cm.OldCustomerCode,
IsCorporateCustomer = cm.IsCorporateCustomer
}).ToListAsync();
But this query doesn't returns as expected. How do I convert this sql query into linq.
Thank you
You didn't tell if list.PortalCustomerDetailViewModel is some information in the database, or in your local process. It seems that this is in your local process, your query will have to transfer it to the database (maybe that is why it is Tmp in your SQL?)
Requirement: give me all properties of a CustomerMaster for all CustomerMasters where exists at least one PortalCustomerDetailViewModel where
customerMaster.CustomerCode == portalCustomerDetailViewModel.NewNLKNo
|| customerMaster.OldAcNo == portalCustomerDetailViewModel.OldNLKNo
You can't use a normal Join, because a Join works with an AND, you want to work with OR
What you could do, is Select all CustomerMasters where there is any PortalCustomerDetailViewModel that fulfills the provided OR:
I only transfer those properties of list.PortalCustomerDetailViewModel to the database that I need to use in the OR expression:
var checkProperties = list.PortalCustomerDetailViewModel
.Select(portalCustomerDetail => new
{
NewNlkNo = portalCustomerDetail.NewNlkNo,
OldNLKNo = portalCustomerDetail.OldNLKNo,
});
var result = dbContext.CustomerMasters.Where(customerMaster =>
checkProperties.Where(checkProperty =>
customerMaster.CustomerCode == checkProperty.NewNLKNo
|| customerMaster.OldAcNo == checkProperty.OldNLKNo)).Any()))
.Select(customerMaster => new CustomerInfoViewModel
{
Id = customerMaster.Id,
Name = customerMaster.Name,
...
});
In words: from each portalCustomerDetail in list.PortalCustomerDetailViewModel, extract the properties NewNKLNo and OldNLKNo.
Then from the table of CustomerMasters, keep only those customerMasters that have at least one portalCustomerDetail with the properties as described in the OR statement.
From every remaining CustomerMasters, create one new CustomerInfoViewModel containing properties ...
select cm.* from Customer cm
inner join #temp tmp
on cm.CustomerCode = tmp.NewNLKNo or cm.OldAcNo = tmp.OldNLKNo
You don't have to use the join syntax. Adding the predicates in a where clause could get the same result. Try to use the following code:
await (from cm in Context.CustomerMaster
from li in list.PortalCustomerDetailViewModel
where cm.CustomerCode == li.NewNLKNo || cm.OldAcNo = li.OldNLKNo
select new CustomerInfoViewModel
{
CustomerId = cm.Id,
CustomerCode = cm.CustomerCode,
CustomerFullName = cm.CustomerFullName,
OldCustomerCode = cm.OldCustomerCode,
IsCorporateCustomer = cm.IsCorporateCustomer
}).ToListAsync();
var result=_db.Customer
.groupjoin(_db.#temp ,jc=>jc.CustomerCode,c=> c.NewNLKNo,(jc,c)=>{jc,c=c.firstordefault()})
.groupjoin(_db.#temp ,jc2=>jc2.OldAcNo,c2=> c2.OldNLKNo,(jc2,c2)=>{jc2,c2=c2.firstordefault()})
.select(x=> new{
//as you want
}).distinct().tolist();
I need to be able to write the following query as a Criteria.
SELECT hist.*
FROM
Administration admin
INNER JOIN Item item ON item.AdministrationId = admin.AdministrationId
INNER JOIN ItemHistory hist ON hist.ItemId = item.ItemId
WHERE
item.itemId = #param
and hist.IsError =
(
SELECT (CASE status.errorType
WHEN 'Warning' THEN 0
ELSE 1
END
)
FROM
AdminStatus status
WHERE
status.AdministrationId = admin.AdministrationId
AND status.Group = 'Issues'
)
I'm pretty sure I'll need to do the sub query as a detached criteria:
var status = DetachedCriteria.For<AdminStatus>("status");
status.CreateAlias("status.Administration", "admin");
status.Add(Restrictions.Eq("status.Group", "Issues"));
status.SetProjection(Projections.Property("AdministrationId"));
status.SetProjection(Projections.Conditional(
Restrictions.Eq("status.errorType", "Warning"),
Projections.Constant(0),
Projections.Constant(1)));
But I'm not sure how to join that with my primary criteria:
var criteria = Session.CreateCriteria<ItemHIstory>("hist");
criteria.CreateAlias("ItemHistory.Item", "item");
criteria.CreateAlias("item.Administration", "admin");
But I'm not sure how to join that with my primary criteria:
Methods from Subqueries class glue detached sub-query with main criteria. Subqueries.PropertyEq in you case:
var criteria = Session.CreateCriteria<ItemHIstory>("hist");
criteria.CreateAlias("ItemHistory.Item", "item");
criteria.CreateAlias("item.Administration", "admin");
criteria.Add(Subqueries.PropertyEq("hist.IsError ", status))
And regarding detached criteria. Alias creation seems unnecessary:
var status = DetachedCriteria.For<AdminStatus>("status");
status.Add(Restrictions.EqProperty("status.AdministrationId", "admin.AdministrationId"));
status.Add(Restrictions.Eq("status.Group", "Issues"));
status.SetProjection(Projections.Conditional(
Restrictions.Eq("status.errorType", "Warning"),
Projections.Constant(0),
Projections.Constant(1)));
I am setting up the query that fetch data from 3 tables based on filters that user select. filters can be multiple or can be none.
I made stored procedures with different combination. But I know that was the worst thing that I did.
var result = (from product in context.Products
from img in context.ProductImage
from saved in context.SavedProduct
where (cat.Color.Contains(product.Color)
& cat.BrandName.Contains(product.Brand_Name)
& cat.Fabric.Contains(product.Fabric)
& cat.Design.Contains(product.Design))
select new
{
product.ProductID,
product.Price,
product.Brand_Name,
product.Title,
product.Color,
product.Fabric,
product.Design,
img.Image,
saved.ProductSavedCounter,
}).ToList();
Product related details in a Product Table. Product images in a ProductImage table. And How many people saved this product are in SavedProduct table.
It returns the products only if user select all filters means when user select red color, Nike brand, cotton fabric etc. If one is missed than this query returns nothing. I want when 1 or 2 are missed than it should return data according to other selected fitters.
Pardon me if there is any mistake I am new bee.
And I missed the joins.
This may help:-
Note: I assumed the ProductID is in the other tables to make the joins, in general if your model have navigation properties for the Product image and save product you would not need the joins.
var result = from product in context.Products
join img in context.ProductImage on product.ProductID equals img.ProductID
join saved in context.SavedProduct on product.ProductID equals saved.ProductID
where (
(string.IsNullOrEmpty(cat.Color) || cat.Color.Equals(product.Color))
& (string.IsNullOrEmpty(cat.BrandName) || cat.Brand_Name.Equals(product.Brand_Name))
& (string.IsNullOrEmpty(cat.Fabric) || cat.Fabric.Equals(product.Fabric))
& (string.IsNullOrEmpty(cat.Design) || cat.Design.Equals(product.Design))
& (
((string.IsNullOrEmpty(cat.Color) ? 1 : 0) +
(string.IsNullOrEmpty(cat.BrandName) ? 1 : 0) +
(string.IsNullOrEmpty(cat.Fabric) ? 1 : 0) +
(string.IsNullOrEmpty(cat.Design) ? 1 : 0)) >= 2) //at least two conditions
)
select new {
product.ProductID,
product.Price,
product.Brand_Name,
product.Title,
product.Color,
product.Fabric,
product.Design,
img.Image,
saved.ProductSavedCounter,
};
I think a better solution would to build it gradually, as below:-
//build the joins
var result = (from product in context.Products
join img in context.ProductImage on product.ProductID equals img.ProductID
join saved in context.SavedProduct on product.ProductID equals saved.ProductID
select new { product, img, saved }).AsQueryable();
//get number of conditions avaliable
var conditionCount = (string.IsNullOrEmpty(cat.Color) ? 1 : 0) +
(string.IsNullOrEmpty(cat.Brand_Name) ? 1 : 0) +
(string.IsNullOrEmpty(cat.Fabric) ? 1 : 0) +
(string.IsNullOrEmpty(cat.Design) ? 1 : 0);
if (conditionCount >= 2)
{
//add the condition if they exists
if (!string.IsNullOrEmpty(cat.Color))
result = result.Where(x => cat.Color.Equals(x.product.Color));
if (!string.IsNullOrEmpty(cat.Brand_Name))
result = result.Where(x => cat.Brand_Name.Equals(x.product.Brand_Name));
if (!string.IsNullOrEmpty(cat.Fabric))
result = result.Where(x => cat.Fabric.Equals(x.product.Fabric));
if (!string.IsNullOrEmpty(cat.Design))
result = result.Where(x => cat.Design.Equals(x.product.Design));
//make the final select
var finalResult = result.Select(x => new
{
x.product.ProductID,
x.product.Price,
x.product.Brand_Name,
x.product.Title,
x.product.Color,
x.product.Fabric,
x.product.Design,
x.img.Image,
x.saved.ProductSavedCounter,
}).ToList();
}
And if you meant that whenever any filter is missing the query should ignore it remove the condition count and the if statement for it.
I'm trying to find an object by checking for several of its relations.
Loan.joins(:credit_memo_attributes)
.where(credit_memo_attributes: {name: 'pr2_gtx1_y', value: '2014'})
.where(credit_memo_attributes: {name: 'pr1_gtx1_y', value: '2013'})
.where(credit_memo_attributes: {name: 'tx1_y', value: '2014'})
Calling to_sql on that gives:
"SELECT `loans`.* FROM `loans` INNER JOIN `credit_memo_attributes`
ON `credit_memo_attributes`.`loan_id` = `loans`.`id`
WHERE `credit_memo_attributes`.`name` = 'pr2_gtx1_y' AND `credit_memo_attributes`.`value` = '2014'
AND `credit_memo_attributes`.`name` = 'pr1_gtx1_y' AND `credit_memo_attributes`.`value` = '2013'
AND `credit_memo_attributes`.`name` = 'tx1_y' AND `credit_memo_attributes`.`value` = '2014'"
So, I'm checking for Loans that have credit_memo_attributes with all of those attributes. I know at least 1 of our 20,000 loans meets this criteria, but this query returns an empty set. If I only use 1 of the where clauses, it returns several, as I'd expect, but once I add even 1 more, it's empty.
Any idea where I'm going wrong?
Update:
Based on comments I believe you want multiple joins in your criteria. You can do that like this:
attr_1 = {name: 'pr2_gtx1_y', value: '2014'}
attr_2 = {name: 'pr1_gtx1_y', value: '2013'}
attr_3 = {name: 'tx1_y', value: '2014'}
Loan.something_cool(attr_1, attr_2, attr_3)
class Loan < ActiveRecord::Base
...
def self.something_cool(attr_1, attr_2, attr_3)
joins(sanitize_sql(["INNER JOIN credit_memo_attributes AS cma1 ON cma1.loan_id = loans.id AND cma1.name = :name AND cma1.value = :value", attr_1]))
.joins(sanitize_sql(["INNER JOIN credit_memo_attributes AS cma2 ON cma2.loan_id = loans.id AND cma2.name = :name AND cma2.value = :value", attr_2]))
.joins(sanitize_sql(["INNER JOIN credit_memo_attributes AS cma3 ON cma3.loan_id = loans.id AND cma3.name = :name AND cma3.value = :value", attr_3]))
end
If you look at the SQL generated (that you included in your question, thank you) you'll see that all those conditions are being ANDed together. There are NO rows for which name = 'pr2_gtx1_y' AND name = 'pr1_gtx1_y' (and so forth). So you are getting the result I would expect (no rows).
You can put all names and values into array like ids and years and pass those into where clause like this. Active Record will query all the values in the array.
Loan.joins(:credit_memo_attributes)
.where(credit_memo_attributes: {name: ids, value: years})
Personally I'm still learning active record, in this concern i don't think active record supports multiple where clauses.
Notice how the SQL version is returning your code: it is joining the requirements with an AND.
"SELECT `loans`.* FROM `loans` INNER JOIN `credit_memo_attributes`
ON `credit_memo_attributes`.`loan_id` = `loans`.`id`
WHERE `credit_memo_attributes`.`name` = 'pr2_gtx1_y' AND `credit_memo_attributes`.`value` = '2014'
AND `credit_memo_attributes`.`name` = 'pr1_gtx1_y' AND `credit_memo_attributes`.`value` = '2013'
AND `credit_memo_attributes`.`name` = 'tx1_y' AND `credit_memo_attributes`.`value` = '2014'"
Now, this is next to impossible. An Object.name can never be all pr2_gtx1_y, pr1_gtx1_y, and tx1_y. Same goes for the value attributes.
What you need here is an OR as opposed to the AND.
To this effect, try to change your query to the following:
Loan.joins(:credit_memo_attributes)
.where(
"credit_memo_attributes.name = ? and credit_memo_attributes.value = ?
OR credit_memo_attributes.names = ? and credit_memo_attributes.value = ?
OR credit_memo_attributes.name = ? and credit_memo_attributes.value = ?",
'pr2_gtx1_y', '2014',
'pr1_gtx1_y', '2013',
'tx1_y', '2014'
)
We are trying to upgrade to NHibernate 3.0 and now i am having problem with the following Linq query. It returns "Only one expression can be specified in the select list when the subquery is not introduced with EXISTS." error.
This is the linq query in the controller.
var list = (from item in ItemTasks.FindTabbedOrDefault(tab)
select new ItemSummary
{
Id = item.Id,
LastModifyDate = item.LastModifyDate,
Tags = (from tag in item.Tags
select new TagSummary
{
ItemsCount = tag.Items.Count,
Name = tag.Name
}).ToList(),
Title = item.Title
});
and the following is the sql generated for this query
select TOP ( 1 /* #p0 */ ) item0_.Id as col_0_0_,
item0_.LastModifyDate as col_1_0_,
(select (select cast(count(* ) as INT)
from dbo.ItemsToTags items3_,
dbo.Item item4_
where tag2_.Id = items3_.Tag_id
and items3_.Item_id = item4_.Id),
tag2_.Name
from dbo.ItemsToTags tags1_,
dbo.Tag tag2_
where item0_.Id = tags1_.Item_id
and tags1_.Tag_id = tag2_.Id) as col_2_0_,
item0_.Title as col_3_0_ from dbo.Item item0_ order by item0_.ItemPostDate desc
ps:If i remove the Tags property in the linq query, it works fine.
Where is the problem in the query?
Thanks in advance.
I've got the same Generic ADO Exception error, I think it's actually the limitation of SQL server;
Is it possible somehow load object graph with projections in collections?
If I try this one:
var cats = q.Select(t => new cat()
{
NickName = t.NickName,
Legs = t.Legs.Select(l => new Leg()
{
Color = l.Color,
Size = l.Size
}).ToList()
}).ToList();
That does the same error..