2017-04-09 75 views
1

我有一个大的学区数据库,从中需要确定术语,学期和整年的开始和结束日期。每个学校都可能有不同的假期(其中周末计算为期限开始日期),尽管这不太可能。 我已经获得了拉到学校,他们的假期和每学期的结束日期,并从中计算出每学期的开始日期。到现在为止还挺好。但有些学校有一些班级在全年(9月至6月)注册。所以,我希望我的最后返回的日期看起来像(这代表了许多学校之一):C#Linq to SQL,查找分组行中的最小和最大日期

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行的Min(TermBegin)和Max(TermEnd)的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 

欣赏帮助,让这远远具有挑战性。

+0

集团通过他们'SchoolId,学年和TermCode'。如果'TermCode'用于'YR'可以是'Year'或其他值,则首先固定在数据库侧的数据。发现用于一年所有不同的代码,使他们都是一样的,一个价值:它是一个代码,所以它应该是相同的。 – CodingYoshi

+0

不幸的是,我无法控制数据。然而TermCode对于年和学校是一致的,所以我删除了那一点。我知道我需要组队,然后选择Min和Max,但我不知道该怎么做。 – Jazzy

回答

0

这里是如何解决这一问题:

  1. 获取所有的记录中,其中TermCodeYR
  2. SchoolIdSchoolYearTermCode和所有的记录中,其中TermCodeYR但他们组TermCodeId,并获得每个组的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和 '最大':

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,第2步将重复的记录,所以我们需要在这里做一些体操删除重复。请参阅this答案以了解如何做到这一点。

请注意我无法编译或测试上面,所以你可能需要调整,但步骤都是那里,因为你拥有的数据,它不应该是很容易做到。

+0

谢谢CodingYoshi,我一直在这个挣扎。我将在明天访问我所有的数据时尝试它,并让你知道它是如何实现的。 – Jazzy