0

如何针对我的和表编写以下LEFT OUTER JOINSQL 查询,以便在 LINQ 中按天、周或月对总销售额进行分组,以便它可以通过 LINQ-to-SQL 实现?CalendarSales

SELECT c.CalendarDate, c.FirstDayOfWeek, c.FirstDayOfMonth,
       ISNULL(s.Total, 0) as Total
FROM Calendar as c
LEFT OUTER JOIN Sales as s
 on s.SaleDate >= c.CalendarDateTime and
    s.SaleDate < c.NextDayDateTime
WHERE s.SaleDate BETWEEN @since and @until

我设法让内部联接在 LINQ 中工作,但我需要外部联接来检索零销售额的天数。这是我用于内部连接的代码:

var sales = from s in db.Sales
            from c in db.Calendars
            where
                s.SaleDate >= c.CalendarDate && s.SaleDate < c.NextDayDateTime
                && s.SaleDate >= sinceDate && s.SaleDate < dateEnd
            select new
            {
                c.CalendarDate,
                c.FirstDateOfWeek,
                c.FirstDateOfMonth,
                s.Total
            };

然后我可以按如下方式打开日期间隔和分组销售:

日常的:

var groupedSales = sales.GroupBy(x => x.CalendarDate);

每周:

var groupedSales = sales.GroupBy(x => x.FirstDateOfWeek);

每月:

var groupedSales = sales.GroupBy(x => x.FirstDateOfMonth);

最后:

var salesReport = from g in groupedSales
                  orderby g.Key
                  select new {
                      Date = g.Key,
                      Total = g.Sum(x => x.Total)
                  };

或者,它也可以在仅检索非零天的销售后将零销售记录注入我的报告中。

4

1 回答 1

0

那这个呢?

var sales = from s in db.Sales
            from c in db.Calendars.DefaultIfEmpty()
            where
                s.SaleDate >= c.CalendarDate && s.SaleDate < c.NextDayDateTime
                && s.SaleDate >= sinceDate && s.SaleDate < dateEnd

编辑: 您可以像这样创建辅助类:

class CalendarSealesHelper
{
   public DateTime CalendarDate {get; set;}
   public DateTime NextDayDateTime {get; set;}
}

class CalendarSealesHelperComparer : IEqualityComparer<CalendarSealesHelper>
{
    public bool Equals(CalendarSealesHelper c1, CalendarSealesHelper c2)
    {
        if (c2.CalendarDate >= c1.CalendarDate 
               && c2.NextDayDateTime < c1.NextDayDateTime)
        {
            return true;
        }
        else
        {
            return false;
        }
    }


    public int GetHashCode(CalendarSealesHelper c)
    {
        int hCode = (int)c.CalendarDate.Ticks ^ (int)c.NextDayDateTime.Ticks;
        return hCode.GetHashCode();
    }
}

然后试试这个:

var query = db.Calendars.GroupJoin(
         db.Sales,
         c => new CalendarSealesHelper{c.CalendarDate, c.NextDayDateTime},
         s => new CalendarSealesHelper{s.SaleDate, s.SaleDate},
         (c, s) => new {Calendars = c, Sales = s},
         new CalendarSealesHelperComparer())
    .SelectMany(s => s.Sales.DefaultIfEmpty(),
            (c, s) => new {
                            CalendarDate = c.CalendarDate,
                            FirstDayOfWeek = c.FirstDayOfWeek,
                            FirstDayOfMonth = c.FirstDayOfMonth,
                            Total = s.Total,
                            SaleDate = s.SaleDate
                          })
    .Where(r => r.SaleDate >= sinceDate && r.SaleDate <= dateEnd); 
于 2012-12-05T15:56:23.400 回答