This question already has answers here:
Group By Multiple Columns
(14 answers)
Closed 6 years ago.
Trying to group by multiple fileds but having issues with it. I want to group by period,productcode.
var ProductUsageSummary = from b in myProductUsage
group b by b.ProductCode into g
select new
{
Period = g.Key,
Code = g.Key,
Count = g.Count(),
TotalQty = g.Sum(n => n.Qty),
Price = g.Average(n => n.Price)
};
also tried
var ProductUsageSummary = from b in myProductUsage
group b by b.Period b.ProductCode into g
select new
{
Period = g.Key(n => n.period),
Code = g.Key,
Count = g.Count(),
TotalQty = g.Sum(n => n.Qty),
Price = g.Average(n => n.Price)
};
You could create an anonymouns object to to group on multiple columns (ex... new {prop1 prop2}) , and the grouped fields can be accessed by Key.PropertyName
Try this.
var ProductUsageSummary = from b in myProductUsage
group b by new { b.Period, b.ProductCode }into g
select new
{
Period= g.Key.Period,
Code = g.Key.ProductCode ,
Count = g.Count(),
TotalQty = g.Sum(n => n.Qty),
Price = g.Average(n => n.Price)
};
This is the correct syntax using Anonymous Types :
group b by new { b.ProductCode, b.Period } into g
Then in select:
g.Key.ProductCode and g.Key.Period
Full Query:
var ProductUsageSummary = from b in myProductUsage
group b by new { b.Period b.ProductCode } into g
select new
{
Period = g.Key.Period,
Code = g.Key.ProductCode,
Count = g.Count(),
TotalQty = g.Sum(n => n.Qty),
Price = g.Average(n => n.Price)
};
Related
What could be the LINQ query for this SQL?
SELECT PartId, BSId,
COUNT(PartId), MAX(EffectiveDateUtc)
FROM PartCostConfig (NOLOCK)
GROUP BY PartId, BSId
HAVING COUNT(PartId) > 1
I am actually grouping by two columns and trying to retrieve max EffectiveDateUtc for each part.
This is what I could write. Stuck up on pulling the top record based on the date.
Also not sure, if this is a optimal one.
//Get all the parts which have more than ONE active record with the pat
//effective date and for the same BSId
var filters = (from p in configs
?.GroupBy(w => new
{
w.PartId,
w.BSId
})
?.Select(g => new
{
PartId = g.Key.PartId,
BSId = g.Key.BSId,
Count = g.Count()
})
?.Where(y => y.Count > 1)
select p)
?.Distinct()?.ToList();
var filteredData = (from p in configs
join f in filters on p.PartId equals f.PartId
select new Config
{
Id = p.Id,
PartId = p.PartId,
BSId = p.BSId,
//EffectiveDateUtc = MAX(??)
}).OrderByDescending(x => x.EffectiveDateUtc).GroupBy(g => new { g.PartId, g.BSId }).ToList();
NOTE: I need the top record (based on date) for each part. Was trying to see if I can avoid for loop.
The equivalent query would be:
var query =
from p in db.PartCostConfig
group p by new { p.PartId, p.BSId } into g
let count = g.Count()
where count > 1
select new
{
g.Key.PartId,
g.Key.BSId,
Count = count,
EffectiveDate = g.Max(x => x.EffectiveDateUtc),
};
If I understand well, you are trying to achieve something like this:
var query=configs.GroupBy(w => new{ w.PartId, w.BSId})
.Where(g=>g.Count()>1)
.Select(g=>new
{
g.Key.PartId,
g.Key.BSId,
Count = g.Count(),
EffectiveDate = g.Max(x => x.EffectiveDateUtc)
});
I am trying to convert this code:
var query2 = from b in db.MU_Reports
join downtime in db.Downtime_Reports on b.Shift equals downtime.Shift
where downtime.Downtime_Code.Equals("9185")
group downtime by new { b.Date, b.Shift, b.Machine_Number, b.MU } into g
select new
{
Date = g.Key.Date,
Shift = g.Key.Shift,
Machine = g.Key.Machine_Number,
MU = g.Key.MU,
No_Work_Hours = g.Sum(x => x.Total_DownTime)
};
To look something like this one:
var query = db.MU_Reports.Join(db.Downtime_Reports, b=> b.Shift, c=> c.Shift, (b , c) => new { b, thisshift = c })
.Where(n => n.thisshift.Down_TIme_Codes.Equals("9185"))
.GroupBy(d=> new { d.b.Date, d.b.Shift, d.b.Machine_Number, d.b.MU }, d => d.b)
.Select (g=> new
{
Date = g.Key.Date,
Shift = g.Key.Shift,
Machine = g.Key.Machine_Number,
MU = g.Key.MU,
No_Work_Hours = g.Sum(i => i.Total_DownTime)
}).ToList();
As you can see I am very close. My only issue is the last statement No_Work_Hours = g.Sum(i => i.Total_DownTime) It is trying to get the Total_DownTime from db.MU_Reports but it needs to come from db.Downtime_Reports. I am new to c# and am doing this to understand the program I created better.
Your second argument to GroupBy should be d => d.thisshift instead of d => d.b. That corresponds to the group downtime by, but by doing d => d.b it's like you're doing group b by
var query = db.MU_Reports
.Join(
db.Downtime_Reports,
b=> b.Shift,
c=> c.Shift,
(b , c) => new { b, thisshift = c })
.Where(n => n.thisshift.Down_TIme_Codes.Equals("9185"))
.GroupBy(
d=> new { d.b.Date, d.b.Shift, d.b.Machine_Number, d.b.MU },
d => d.thisshift)
.Select (g=> new
{
Date = g.Key.Date,
Shift = g.Key.Shift,
Machine = g.Key.Machine_Number,
MU = g.Key.MU,
No_Work_Hours = g.Sum(i => i.Total_DownTime)
})
.ToList();
I need to group on dept and needWeek and then add sum together, add open together, and add closed together.
This query:
var query8 = from q8 in query7
group q8 by new { q8.q7.dept, q8.needWeek, q8.q7.allCount, q8.q7.openCount, q8.q7.closedCount } into g
select new
{
dept = g.Key.dept,
needWeek = g.Key.needWeek,
sum = g.Sum(q8 => g.Key.allCount),
open = g.Sum(q8 => g.Key.openCount),
closed = g.Sum(q8 => g.Key.closedCount)
};
will return:
{ dept = foo, needWeek = 05/20/12, sum = 7, open = 3, closed = 4 }
{ dept = foo, needWeek = 05/20/12, sum = 2, open = 0, closed = 2 }
but I need:
{ dept = foo, needWeek = 05/20/12, sum = 9, open = 3, closed = 6 }
How close am I?
You are close, but you're grouping by all unnecessary fields. Just group by what is common to all.
var query8 =
from q8 in query7
group new { q8.q7.allCount, q8.q7.openCount, q8.q7.closedCount }
by new { q8.q7.dept, q8.needWeek }
into g
select new
{
g.Key.dept,
g.Key.needWeek,
sum = g.Sum(x => x.allCount),
open = g.Sum(x => x.openCount),
closed = g.Sum(x => x.closedCount),
};
I need to group on dept and needWeek
So why doesn't your code follow your needs? Why are you grouping by everything?
group q8 by new { q8.q7.dept, q8.needWeek } into g
select new
{
dept = g.Key.dept,
needWeek = g.Key.needWeek,
sum = g.Sum(q8 => g.q7.allCount),
open = g.Sum(q8 => g.q7.openCount),
closed = g.Sum(q8 => g.q7.closedCount)
};
i am writing the following linq code in c#
var groupedData = from b in dt.AsEnumerable()
group b by b.Field<string>("TypeColor") into g
select new
{
Key = g.Key,
Value = g.Select(r => r.Field<int>("Price")),
Price = g.Select(r => r.Field<int>("Price"))
};
foreach (var g in groupedData)
{
string s = g.Key;
}
how can i select two or more field from the datatable and group the table with one field.
Can any body help me?
Here dt is a datatable which is binding from database
You need to aggregate the fields if you've grouped the rows(similar as in SQL):
var groupedData = from b in dt.AsEnumerable()
group b by b.Field<string>("TypeColor") into g
select new
{
Color = g.Key,
PriceSum = g.Sum(r => r.Field<int>("Price")),
FirstValue = g.First().Field<int>("Value")
};
foreach (var g in groupedData)
{
string color = g.Color;
Double priceSum = g.PriceSum;
int firstValue = g.FirstValue;
}
List<int> ListIdProducts = new List<int>();
var IdProductKey = from a in me.ProductKeywords where a.Keyword == item.Id select a;
foreach (var item2 in IdProductKey)
{
ListIdProducts.Add(item2.Product.Value);
}
Result is:
5
6
7
5
2
5
I need to get the following 5=3, 6=1, 7=1, 2=1
Use GroupBy LINQ method:
ListIdProducts
.GroupBy(i => i)
.Select(g => new { Value = g.Key, Count = g.Count() });
var query1 = from a in ListIdProducts
group a by new { a } into g
select new
{
item = g.Key,
itemcount = g.Count()
};
This a fairly standard group-by problem.
//untested
var IdProducts = from a in me.ProductKeywords
where a.Keyword == item.Id
group by a.Product.Value into g
select g.Count();