Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

How to group by and sum in linq

Posted on 2013-12-02
2
696 Views
Last Modified: 2016-02-10
I have a list <T>

within which i have four fields

Code   - string
ProductGroup string
Price - decimal
BusinessDate - datetime


I need to Group by  ProductGroup, and BusinessDate ( just the month and year part)
Meaning all dates in a month are grouped, and I need to sum the Price to give me a new list

T1

with

ProductGroup
BusDate ( this would hold just 01/MM/YYYY)
Price (sum of all prices in that month
0
Comment
Question by:countrymeister
  • 2
2 Comments
 
LVL 11

Expert Comment

by:Angelp1ay
ID: 39691268
        private class InputType
        {
            public String Code;
            public String ProductGroup;
            public Decimal Price;
            public DateTime BusinessDate;
        }

        private class ResultType
        {
            public String ProductGroup;
            public Decimal Sum;
            public DateTime Month;
        }

        public void MyFunction()
        {

            List<InputType> input = new List<InputType>();

            IEnumerable<ResultType> output = from c in input
                                             group c by new
                                             {
                                                 c.ProductGroup,
                                                 c.BusinessDate.Year,
                                                 c.BusinessDate.Month,
                                             } into grp
                                             select new ResultType()
                                             {
                                                 ProductGroup = grp.Key.ProductGroup,
                                                 Month = new DateTime(grp.Key.Year, grp.Key.Month, 1),
                                                 Sum = grp.Sum(s => s.Price),
                                             };
        }

Open in new window

0
 
LVL 11

Accepted Solution

by:
Angelp1ay earned 500 total points
ID: 39691738
I figured I should put some example data in and explain better. I've added some data for Product Groups "G1" and "G2" spread over January and February and I've also added a second output which does exactly the same in Linq Method Syntax.

        public void MyFunction()
        {
            List<InputType> input = new List<InputType>();
            input.Add(new InputType() { Code = "C123", ProductGroup = "G1", Price = 1.00m, BusinessDate = new DateTime(1, 1, 1) });
            input.Add(new InputType() { Code = "C124", ProductGroup = "G1", Price = 2.00m, BusinessDate = new DateTime(1, 1, 15) });
            input.Add(new InputType() { Code = "C125", ProductGroup = "G1", Price = 3.00m, BusinessDate = new DateTime(1, 2, 4) });
            input.Add(new InputType() { Code = "C126", ProductGroup = "G1", Price = 4.00m, BusinessDate = new DateTime(1, 2, 26) });
            input.Add(new InputType() { Code = "C123", ProductGroup = "G2", Price = 1.00m, BusinessDate = new DateTime(1, 1, 1) });
            input.Add(new InputType() { Code = "C124", ProductGroup = "G2", Price = 1.00m, BusinessDate = new DateTime(1, 1, 15) });
            input.Add(new InputType() { Code = "C125", ProductGroup = "G2", Price = 1.00m, BusinessDate = new DateTime(1, 1, 4) });
            input.Add(new InputType() { Code = "C126", ProductGroup = "G2", Price = 1.00m, BusinessDate = new DateTime(1, 2, 26) });

            IEnumerable<ResultType> output = from c in input
                                             group c by new
                                             {
                                                 c.ProductGroup,
                                                 c.BusinessDate.Year,
                                                 c.BusinessDate.Month,
                                             } into grp
                                             select new ResultType()
                                             {
                                                 ProductGroup = grp.Key.ProductGroup,
                                                 Month = new DateTime(grp.Key.Year, grp.Key.Month, 1),
                                                 Sum = grp.Sum(s => s.Price),
                                             };

            IEnumerable<ResultType> output2 = input
                .GroupBy(x => new {x.ProductGroup,
                                   x.BusinessDate.Year,
                                   x.BusinessDate.Month})
                .Select(grp => new ResultType() {ProductGroup = grp.Key.ProductGroup, 
                                                 Month = new DateTime(grp.Key.Year, grp.Key.Month,1), 
                                                 Sum = grp.Sum(i => i.Price)});
        }

Open in new window

Both outputs do the same thing - the first is Linq Query Syntax, the second is Linq Method Syntax (but they both do exactly the same thing under the hood). You can use whichever you're more comfortable with or you find easier to read/maintain.

First I group using an anonymous type that contains all the attributes you want to group on (the product group, year and month).

Then I project the results into the desired target type, extracting the Product Group, Year and Month from the group, wrapping the Year and Month in a new DateTime, and finally by summing the price across the group.

As you can see in this debug screenshot, it works as expected (showing the second group which is Product Group G1 in Feb).
Stepping through showing Linq in action
0

Featured Post

MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question