2009-10-08 16 views
18

Tengo una tabla de ventas de productos que tiene este aspecto:grupo múltiple de y Suma LINQ

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

Necesito hacer la suma de cada mes por lo que la mesa final se vería así:

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

¿Puedo hacer esto con LINQ?

Respuesta

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

Vaya que fue muy lejos de mi comprensión si LINQ .... voy a probar esto, entonces contesta .. gracias – Luiscencio

+0

Si está ejecutando esto en SQL, dígame cómo funciona. –

+0

funcionó bastante bien, solo tuve que modificar algunos detalles, estoy usando esto contra un objeto de datatabel, lo intentaré más tarde contra SQL ... thans = 3 – Luiscencio

2

Sure.

Se verá así:

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) }; 

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

También, nota que estaba operando bajo el supuesto de que el conjunto de datos sólo tenía datos de 2009. Si desea agrupar por mes/año, puede usar saleDate.ToString ("yyyyMM") en lugar de saleDate.Month.

+0

También puede utilizar (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; } 
}