[英]C# Linq to SQL, find Min and Max dates in grouped rows
我有一个大型学区数据库,我需要从中确定术语,学期和全年的开始和结束日期。 每个学校可能有不同的假期(与周末一起计算到学期开始日期),尽管不太可能。 我已经达到了拉动学校,他们的假期和每个学期的结束日期,并从计算出每个学期的开始日期。 到现在为止还挺好。 但是有些学校有一些课程和其他课程注册了全年(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行的Min(TermBegin)和Max(TermEnd)。 我需要对SchoolId和TermCode进行分组并获取每个唯一代码的Min和Max,但我不知道如何。
我从上面的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
感谢帮助,实现这一目标具有挑战性。
以下是解决此问题的方法:
TermCode
不是YR
所有记录 TermCode
为YR
所有记录,但按SchoolId
, SchoolYear
, TermCode
和TermCodeId
它们进行SchoolId
,并获取每个组的Max(TermBegin)
和Max(TermEnd)
。 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 by
和Min
和'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
,第二步将有重复的记录,所以我们需要在这里做一些体操来删除重复。 请参阅此答案,了解如何执行此操作。
请注意我无法编译或测试上面所以你可能需要调整它,但步骤都在那里,因为你有数据,这应该不容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.