如何在LEFT OUTER JOIN
和Calendar
表中编写以下Sales
SQL查询,以便在LINQ中按日,周或月对总计销售进行分组,以便它可以由LINQ-to-SQL实现?
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)
};
或者,它也可以在检索非零日销售后,将零销售记录注入我的报告中。
答案 0 :(得分: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);