0

LINQ-to-SQL で具体化できるように、LINQ で合計売上高を日、週、または月ごとにグループ化する目的で、テーブルとテーブルLEFT OUTER JOINに対して次の 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 に答える