C# Linq to SQL,在分组行中查找最小值和最大值日期



>我有一个大型学区数据库,我需要从中确定学期、学期和整年的开始和结束日期。每所学校可能有不同的假期(与周末一起计入学期开始日期),尽管不太可能。 我已经把学校、他们的假期和每个学期的结束日期拉出来,然后计算出每个学期的开始日期。目前为止,一切都好。但有些学校有一些学期注册的课程,而另一些课程则是全年(9月至6月)。所以我希望我的最终返回日期看起来像(这代表许多学校之一):

SchoolId SchoolYear TermCode    TermBegin        TermEnd      TermCodeId
8CFD1     2016      TM1         08/29/2016       10/07/2016     F375E7
8CFD1     2016      TM2         10/10/2016       11/25/2016     898EF5
8CFD1     2016      TM3         11/28/2016       02/01/2017     F5140C
8CFD1     2016      TM4         02/02/2017       03/10/2017     DD95B1
8CFD1     2016      TM5         03/13/2017       05/05/2017     BE3635
8CFD1     2016      TM6         05/08/2017       06/09/2017     2B94F0
8CFD1     2016      YR          08/29/2016       06/09/2017     D97C9C

我得到的最接近的是这个查询(使用我计算开始日期的结果):

from tdf in ReturnFromCalculatingStartDate 
join tcd in SCH_YR_TRM_CODES on tdf.SchoolYearTermDefGu equals tcd.SCHOOL_YEAR_TRM_DEF_GU
orderby tcd.TERM_CODE
select new TermResult {     
SchoolId = testOrgGu,
SchoolYear = testSchoolyear,
TermCode = tcd.TERM_CODE,
TermBegin = tdf.TermStartDate,
TermEnd = tdf.TermEndtDate,
TermCodeId = tcd.SCHOOL_YEAR_TRM_CODES_GU

它正确返回术语,但我每个术语都有一年 (YR)。我需要的是一行 YR 行,其中包含 YR 行的最小值(术语开始)和最大值(术语结束)。我需要对SchoolId和TermCode进行分组,并获取每个唯一代码的最小值和最大值,但我不知道如何操作。

我从上面的 Linq 得到的数据如下。 Min(TermBegin) YR 行中的 TermCodeId 是我需要在结果中使用的 TermCodeId。

SchoolId    SchoolYear  TermCode  TermBegin    TermEnd     TermCodeId
8CFD1    2016         TM1        08/29/2016  10/07/2016  F375E7
8CFD1    2016         TM2        10/10/2016  11/25/2016  898EF5
8CFD1    2016         TM3        11/28/2016  02/01/2017  F5140C
8CFD1    2016         TM4        02/02/2017  03/10/2017  DD95B1
8CFD1    2016         TM5        03/13/2017  05/05/2017  BE3635
8CFD1    2016         TM6        05/08/2017  06/09/2017  2B94F0
8CFD1    2016         YR         08/29/2016  10/07/2016  d97C9C
8CFD1    2016         YR         10/10/2016  11/25/2016  e30980
8CFD1    2016         YR         11/28/2016  02/01/2017  ef5de2
8CFD1    2016         YR         02/02/2017  03/10/2017  bbe78f
8CFD1    2016         YR         03/13/2017  05/05/2017  ca28a7
8CFD1    2016         YR         05/08/2017  06/09/2017  2340c1

感谢您的帮助,走到这一步具有挑战性。

以下是解决此问题的方法:

  1. 获取TermCodeYR的所有记录
  2. 获取TermCodeYR的所有记录,但按SchoolIdSchoolYearTermCodeTermCodeId对它们进行分组,并获取每个组的Max(TermBegin)Max(TermEnd)
  3. 对上述步骤 1 和 2 中的结果执行Union

步骤 1

我们需要做的就是向查询添加一个where子句,如下所示:

where tcd.TERM_CODE != "YR"

但是,让我们将查询保存在变量中,以便更具可读性。请注意添加where条款:

var excludingYr =
from tdf in ReturnFromCalculatingStartDate
join tcd in SCH_YR_TRM_CODES on tdf.SchoolYearTermDefGu
equals tcd.SCHOOL_YEAR_TRM_DEF_GU
where tcd.TERM_CODE != "YR"
orderby tcd.TERM_CODE
select new TermResult
{
SchoolId = testOrgGu,
SchoolYear = testSchoolyear,
TermCode = tcd.TERM_CODE,
TermBegin = tdf.TermStartDate,
TermEnd = tdf.TermEndtDate,
TermCodeId = tcd.SCHOOL_YEAR_TRM_CODES_GU
};

步骤 2

我们需要添加一个where子句和一个group byMin和"Max":

var yearRecords =
from tdf in ReturnFromCalculatingStartDate
join tcd in SCH_YR_TRM_CODES on tdf.SchoolYearTermDefGu
equals tcd.SCHOOL_YEAR_TRM_DEF_GU
where tcd.TERM_CODE == "YR"
orderby tcd.TERM_CODE
group tdf by new
{
SchoolId = testOrgGu,
SchoolYear = testSchoolyear,
TermCode = tcd.TERM_CODE,
TermCodeId = tcd.SCHOOL_YEAR_TRM_CODES_GU
} into yrs
select new TermResult
{
SchoolId = yrs.Key.SchoolId,
SchoolYear = yrs.Key.testSchoolyear,
TermCode = yrs.Key.TermCode,
TermBegin = yrs.Min(x => x.TermBegin),
TermEnd = yrs.Max(x => x.TermBegin),
TermCodeId = yrs.Key.TermCodeId
};

步骤 3

让我们执行一个Union

var finalQuery = excludingYr.Union(yearRecords);

因为你需要TermCodeId,第二步会有重复的记录,所以我们需要在这里做一些体操来删除重复。请参阅此答案以了解如何完成该部分。

请注意,我无法编译或测试上述内容,因此您可能需要对其进行调整,但步骤都在那里,并且由于您有数据,因此应该不容易做到。

最新更新