如何添加新年?

How to add new year?

我想在上一学年结束后每次增加学年。例如,我当前的代码如下所示:

WHERE schooldt BETWEEN '07/01/2016' AND '06/30/2017'

所以一旦学年结束 06/30/2017 我想自动设置新的开始日期和新的结束日期。我正在考虑在冷​​聚变中使用 dateAdd() 。有没有其他方法可以做到这一点,什么方法最有效?

提前致谢。

I would like to increment school year every time after previous school year is over

然后实施根据当前月份更改查询中使用的日期值的逻辑。如果当前月份早于 7 月,则您知道当前学年仍在进行中。所以减去一年来计算开始日期。否则,移至下一年。

    <cfset today = now()>
    <!--- If the current school year is still in progress --->
    <cfif month(today) lt 7>
        <cfset startDate = createDate( year(today) - 1, 7, 1)>
        <cfset endDate = createDate( year(today), 6, 30)>
    <!--- Otherwise, move to next year --->
    <cfelse>
        <cfset startDate = createDate( year(today), 7, 1)>
        <cfset endDate = createDate( year(today) + 1, 6, 30)>
    </cfif>

就查询而言,要记住两点:

  • 日期字符串不明确。始终使用日期对象。
  • 小心日期比较和 BETWEEN 运算符。如果 SchoolDt 列同时包含日期和时间,则结果可能不是您所期望的。一个更灵活的结构(即使列同时包含日期和时间也仍然有效)是:

    WHERE SchoolDt >= <cfqueryparam value="#startDate#" cfsqltype="cf_sql_date">
    AND   SchoolDt < <cfqueryparam value="#dateAdd('d', 1, endDate)#" cfsqltype="cf_sql_date">
    

    如果您使用 new Query(),请参数化 sql 字符串并改用 addParam

    yourQuery.addParam( name="startDate"
                       , value="#startDate#"
                       , cfsqltype="cf_sql_date" );
    
    yourQuery.addParam( name="endDate"
                       , value="#endDate#"
                       , cfsqltype="cf_sql_date" );
    

日期table答案:

CREATE TABLE calendar ( 
    SeqNum int
    , schooldt date NOT NULL PRIMARY KEY
    , theYear int
    , theMonth tinyint
    , theDay tinyint
    , schoolyear int
    , isSchoolDay tinyint   /* Can count schooldays */ 
    , isHoliday tinyint /* Can count holidays. */
)

DECLARE @StartDate date = '1/1/2010'

/* Build tally table with 10^x rows */
; WITH TallyTable (x) AS
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(x)       -- 10 days
    CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(x) -- 100 days
    CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(x) -- 1000 days
    CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d(x) -- 10000 days
)
INSERT INTO calendar ( SeqNum, schooldt, theYear, theMonth, theDay, schoolyear, isSchoolDay, isHoliday )
SELECT 
    tt.x AS SeqNum
    , d1.theDate
    , d2.theYear
    , d2.theMonth
    , d2.theDay
    , d2.theSchoolYear
    , 1 , 0 /* Defaults for isSchoolDay and isHoliday. Add if needed. */
FROM TallyTable tt
CROSS APPLY (
    SELECT theDate = DATEADD(dd, (tt.x-1), @StartDate) /* Starting date */
) d1
CROSS APPLY 
(  
    SELECT  theYear = DATEPART(yy,d1.theDate)
        , theMonth = DATEPART(mm,d1.theDate)
        , theDay = DATEPART(dd,d1.theDate) 
        , theSchoolYear = CASE WHEN DATEPART(mm,d1.theDate) < 7 THEN DATEPART(yyyy,d1.theDate) ELSE DATEPART(yyyy,d1.theDate)+1 END
) d2;

沿着这些路线的东西会给你几年后的日子列表。然后你可以加入这个 table 以获得你想要的范围。

要改进 table,您可以包含信息以标记假期和周末,这样您就只能看到学校实际开课的日子。最重要的是,您可以按您希望看到的当前学年过滤所有内容。当需要改变时,您不必担心增加学年。

但这又引出了一个问题,这个查询的最终目标是什么?可能有更好的方法来实现您的最终目标。