我想在上一学年结束后每次增加学年。例如,我当前的代码如下所示:
WHERE schooldt BETWEEN '07/01/2016' AND '06/30/2017'
因此,一旦学年结束06/30/2017
,我想自动设置新的开始日期和新的结束日期。我在考虑在冷聚变中使用dateAdd()。有没有其他方法可以做到这一点以及什么是最有效的?
提前致谢。
答案 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;
这些方面的内容将为您提供几年的日期清单。然后,您可以加入此表以获得所需的范围。
要改进表格,您可以添加信息以标记假期和周末,这样您只能看到学校实际上在会话中的日子。最重要的是,您可以在您希望看到的当前学年中对其进行过滤。在没有时间改变时,你不必担心增加学年。
但它再次引出了一个问题,这个查询的最终目标是什么?可能有更好的方法来实现你的最终目标。