如何添加新年?

时间:2016-09-09 15:43:58

标签: coldfusion dateadd

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

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

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

提前致谢。

2 个答案:

答案 0 :(得分:6)

  

我想在上一学年结束后每次增加学年

然后实现逻辑,根据当前月份更改查询中使用的日期值。如果当前月份早于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" );
    

答案 1 :(得分:2)

对于日期表答案:

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;

这些方面的内容将为您提供几年的日期清单。然后,您可以加入此表以获得所需的范围。

要改进表格,您可以添加信息以标记假期和周末,这样您只能看到学校实际上在会话中的日子。最重要的是,您可以在您希望看到的当前学年中对其进行过滤。在没有时间改变时,你不必担心增加学年。

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