GroupBy和Sum有两个不同的时期 - Linq

时间:2017-07-03 13:22:57

标签: c# linq

我需要在一行中的不同时间段内获得我的产品总量。

例如:

ID     Date       Amount
-------------------------
1     2017/01/01   10
1     2017/01/01   12
1     2017/04/03   5
2     2017/01/02   10

我需要得到每种产品的春季和夏季的总和,所以我们对产品1有这个:

ID     SumSpring    SumSummer
-----------------------------
1        22            5

我使用过这段代码:

    var pDetails = ordersTotal.Select(g => new
                                {
                                    g.ProductID,
                                    DateType = (((String.Compare(g.BuyDate, "2017/01/01") >= 0 && String.Compare(g.BuyDate, "2017/03/30") <= 0)) ? "Spring" : "Summer"),
                                    g.Amount
                                }).GroupBy(x => new { id = x.ProductID, type = x.DateType }).Select(x => new
                                {
                                    ProductID = x.Key.id,
                                    SumSpring = (x.Where(z => z.DateType == "Spring").Count() == 0 ? 0 : x.Where(z => z.DateType == "Spring").Sum(z => z.Amount)),
                                    SumSummer = (x.Where(z => z.DateType == "Summer").Count() == 0 ? 0 : x.Where(z => z.DateType == "Summer").Sum(z => z.Amount)),
                                });

但它会为每个产品返回几行,这不是我的预期,我不知道为什么!

这是一种产品的输出:

ID     SumSpring    SumSummer
-----------------------------
1        22            0
1        0             5

一个产品有两行,但应该是一行!

2 个答案:

答案 0 :(得分:2)

你可以用这种方式获得一年的时间:

int quarter = (month + 2) / 3;

但请勿将其包含在GroupBy中,您只想按ProductID分组

var pDetails = ordersTotal.Select(x => new
{
    x.ProductID,
    x.Amount,
    Quarter = (x.BuyDate.Month + 2) / 3
})
.Where(x => x.Quarter == 1 || x.Quarter == 2)  // it seems you only want these
.GroupBy(x => x.ProductID)
.Select(g => new
{
    ProductID = g.Key,
    SumSpring = g.Where(x => x.Quarter == 1)
                 .Select(x => x.Amount)
                 .DefaultIfEmpty(0)
                 .Sum(),
    SumSummer = g.Where(x => x.Quarter == 2)
                 .Select(x => x.Amount)
                 .DefaultIfEmpty(0)
                 .Sum()
});

请注意,此查询并不关心这一年。但无论如何你似乎并不关心它。

答案 1 :(得分:2)

试试以下内容。主要问题是你按金额分组:

           var pDetails = ordersTotal.Select(g => new
            {
                ProductID = g.ProductID,
                DateType = ((g.BuyDate >= DateTime.Parse("1/1/17")) && (g.BuyDate <=  DateTime.Parse("3/30.17"))) ? "Spring" : "Summer",
                Amount = g.Amount
            }).GroupBy(x => new { id = x.ProductID}).Select(x => new
            {
                ProductID = x.Key.id,
                SumSpring = x.Where(z => z.DateType == "Spring").Sum(z => z.Amount),
                SumSummer = x.Where(z => z.DateType == "Summer").Sum(z => z.Amount),
            }).ToList();