简体   繁体   English

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

[英]C# Linq to SQL, find Min and Max dates in grouped rows

I have a large school district database, from which I need to determine the start and end dates for terms, semesters, and full years. 我有一个大型学区数据库,我需要从中确定术语,学期和全年的开始和结束日期。 Each school could have different holidays (which along with weekends calculate into the term start date), though it's not likely. 每个学校可能有不同的假期(与周末一起计算到学期开始日期),尽管不太可能。 I have gotten as far as pulling the schools, their holidays, and the END date of each term and from that calculated the beginning date of each term. 我已经达到了拉动学校,他们的假期和每个学期的结束日期,并从计算出每个学期的开始日期。 So far so good. 到现在为止还挺好。 But some schools have some classes registered in terms and other classes that are full year (September to June). 但是有些学校有一些课程和其他课程注册了全年(9月至6月)。 So I want my final returned date to look something like (this represents one of many schools): 所以我希望我的最终返回日期看起来像(这代表了许多学校之一):

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

The closest I have gotten is this query (using results where I have calculated the start date): 我得到的最接近的是这个查询(使用我计算开始日期的结果):

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

Which returns the terms correctly, but I get a year (YR) for each term. 这正确地返回了条款,但每个学期我得到一年(YR)。 What I need is one YR row that has the Min(TermBegin) and the Max(TermEnd) of the YR rows. 我需要的是一个YR行,它具有YR行的Min(TermBegin)和Max(TermEnd)。 I would need to group on the SchoolId and TermCode and get the Min and Max of each unique code, but I don't know how. 我需要对SchoolId和TermCode进行分组并获取每个唯一代码的Min和Max,但我不知道如何。

The data I get back from the above Linq is below. 我从上面的Linq得到的数据如下。 The TermCodeId from the Min(TermBegin) YR row is the TermCodeId I need to have in my results. 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

Appreciate the help, getting this far was challenging. 感谢帮助,实现这一目标具有挑战性。

Here is how to tackle this issue: 以下是解决此问题的方法:

  1. Get all the records where the TermCode is NOT YR 获取TermCode不是YR所有记录
  2. Get all the records where the TermCode is YR but group them by SchoolId , SchoolYear , TermCode and TermCodeId and get the Max(TermBegin) and Max(TermEnd) for each group. 获取TermCodeYR所有记录,但按SchoolIdSchoolYearTermCodeTermCodeId它们进行SchoolId ,并获取每个组的Max(TermBegin)Max(TermEnd)
  3. Perform a Union on results in step 1 and 2 above. 在上面的步骤1和2中对结果执行Union

Step 1 第1步

All we need to is to add a where clause to your query like this: 我们需要的是为您的查询添加一个where子句,如下所示:

where tcd.TERM_CODE != "YR"

But lets save the query in a variable so it is more readable. 但是我们将查询保存在变量中,以便更具可读性。 Please note the addition of the where clause: 请注意添加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
    };

Step 2 第2步

We need to add a where clause and a group by and Min and 'Max': 我们需要添加一个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
    };

Step 3 第3步

Let's perform a Union : 让我们Union

var finalQuery = excludingYr.Union(yearRecords);

Because you need the TermCodeId , the 2nd step will have duplicate records so we need to do some gymnastics here to remove duplications. 因为你需要TermCodeId ,第二步将有重复的记录,所以我们需要在这里做一些体操来删除重复。 See this answer to see how you can do that part. 请参阅答案,了解如何执行此操作。

Please note I could not compile or test the above so you may need to tweak it but the steps are all there and since you have the data, it should not be easy to do. 请注意我无法编译或测试上面所以你可能需要调整它,但步骤都在那里,因为你有数据,这应该不容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM