2009-10-08 23 views
18

Mam tabeli produkty sprzedaży, który wygląda tak:Multiple grupa przez i Sum LINQ

saleDate  prod  qty 
10/22/09  soap  10 
09/22/09  pills  05 
09/25/09  soap  06 
09/25/09  pills  15 

muszę dokonać sumy co miesiąc, więc ostateczna tabela będzie wyglądać następująco:

saleDate  prod  qty 
10/09  soap  10 
09/09  soap  06 
09/09  pills  20 

Czy mogę to zrobić z LINQ?

Odpowiedz

44
var products = new[] { 
    new {SaleDate = new DateTime(2009,10,22), Product = "Soap", Quantity = 10}, 
    new {SaleDate = new DateTime(2009,09,22), Product = "Pills", Quantity = 5}, 
    new {SaleDate = new DateTime(2009,09,25), Product = "Soap", Quantity = 6}, 
    new {SaleDate = new DateTime(2009,09,25), Product = "Pills", Quantity = 15} 
}; 

var summary = from p in products 
       let k = new 
       { 
        //try this if you need a date field 
        // p.SaleDate.Date.AddDays(-1 *p.SaleDate.Day - 1) 
        Month = p.SaleDate.ToString("MM/yy"), 
        Product = p.Product 
       } 
       group p by k into t 
       select new 
       { 
        Month = t.Key.Month, 
        Product = t.Key.Product, 
        Qty = t.Sum(p => p.Quantity) 
       }; 

foreach (var item in summary) 
    Console.WriteLine(item); 

//{ Month = 10/09, Product = Soap, Qty = 10 } 
//{ Month = 09/09, Product = Pills, Qty = 20 } 
//{ Month = 09/09, Product = Soap, Qty = 6 } 
+0

Wow to było daleko moje zrozumienie jeśli LINQ .... Postaram się to wtedy odpowiadać .. dzięki – Luiscencio

+0

Jeśli używasz tego przeciwko SQL, daj mi znać, jak to działa. –

+0

to działało całkiem nieźle, po prostu musiałem zmodyfikować pewne szczegóły, używam tego przeciwko obiektowi datatabel, spróbuj go później z SQL ... thans = 3 – Luiscencio

2

Pewnie.

To będzie wyglądać następująco:

var GroupedSales = 
     from p in products 
     group p by p.saleDate.Month into g 
     select new { saleMonth = g.saleDate.Month, QtySold = g.Sum(p => p.qty) }; 

Patrz: http://msdn.microsoft.com/en-us/vcsharp/aa336747.aspx#sumGrouped

Należy również pamiętać, że byłem działający przy założeniu, że zestaw danych miał tylko dane 2009. Jeśli chcesz grupować według miesiąca/roku, możesz użyć saleDate.ToString ("yyyyMM") zamiast saleDate.Month.

+0

Można również użyć (saleDate.Year * 12 + saleDate.Month) –

4
var q = from s in sales 
     group s by new {saleDate = s.saleDate.ToString("MM/yy"), s.prod} into g 
     select new { g.Key.saleDate, g.Key.prod, qty = g.Sum(s => s.qty) }; 
3
class Program 
{ 
    static void Main(string[] args) 
    { 
     var sales = new List<Sale>(); 
     sales.Add(new Sale() { Product = "soap", saleDate = new DateTime(2009, 10, 22), Quantity = 10}); 
     sales.Add(new Sale() { Product = "soap", saleDate = new DateTime(2009, 9,22), Quantity = 6}); 
     sales.Add(new Sale() { Product = "pills", saleDate = new DateTime(2009,9,25), Quantity = 15}); 
     sales.Add(new Sale() { Product = "pills", saleDate = new DateTime(2009,9,25), Quantity = 5}); 

     var q = from s in sales 
       group s by new { s.Product, s.saleDate.Month, s.saleDate.Year } into g 
       select new {Month = String.Format("{0:MM/yy}", new DateTime(g.Key.Year, g.Key.Month, 1)), product = g.Key.Product, quantity = g.Sum(o=>o.Quantity)}; 


    } 
} 

class Sale 
{ 
    public DateTime saleDate { get; set; } 
    public int Quantity { get; set; } 
    public string Product { get; set; } 
}