我有一张包含Amounts和Created Dates的表格。我想创建一个循环查询 - AND更改查询中的日期。否则我必须手动完成。
当前查询:
<cfquery name=qWeekly datasource="#DSN#">
SELECT SUM(Amount)
FROM Transactions
WHERE ( CreatedDate BETWEEN '1-19-2014' AND '1-25-2014' )
AND ( Amount > 0 )
</cfquery>
我会手动将过滤器更改为... (CreatedDate BETWEEN '1-19-22014' AND '1-25-2014')...
,然后再次手动将其更改为:(CreatedDate ...BETWEEN '1-26-2014' AND '2-8-2014')
。
我想做的是类似Between 'X' AND 'X+7'
,这样我可以获得一周的数据,增加7天,这样我就可以按周日期范围生成输出。在伪代码中,像这样:
<cfif CreatedDate < Now()>
<cfloop index="x" step="7">
<cfquery name=qWeekly datasource="#DSN#">
SELECT SUM(Amount)
FROM Transactions
WHERE ( CreatedDate BETWEEN 'x' AND 'x+7' )
AND ( Amount > 0 )
</cfquery>
</cfloop>
</cfif>
这可能吗?
答案 0 :(得分:1)
你没有提到你的dbms(总是很好地将它包含在sql问题中)但是你可以在没有循环的情况下实现目标。例如,在SQL Server中,您可以使用CTE生成一周的开始日期表。然后将其加入到您的交易表中,并按周汇总金额。
<强> SQLFiddle 强>
<!--- Example: generate a range of 7 weeks --->
<cfset firstSunday = createDate(2014,1,19)>
<cfset lastSunday = dateAdd("ww", 7, firstSunday)
...
<!--- Calculate totals for all weeks in range --->
<cfquery name="getTotalsByWeek" ...>
;WITH ranges ( WeekStartDate ) AS (
SELECT <cfqueryparam value="#firstSunday#" cfsqltype="cf_sql_date"> AS WeekStartDate
UNION ALL
SELECT DATEADD(d, 7, WeekStartDate)
FROM ranges
WHERE <cfqueryparam value="#lastSunday#" cfsqltype="cf_sql_date"> > WeekStartDate
)
SELECT r.WeekStartDate, SUM(t.Amount) AS TotalAmount
FROM ranges r LEFT JOIN Transactions t
<!--- CreatedDate falls within 7 days of the start date --->
ON t.CreatedDate >= r.WeekStartDate
AND t.CreatedDate < DATEADD(d, 8, r.WeekStartDate)
GROUP BY r.WeekStartDate
ORDER BY r.WeekStartDate
</cfquery>
<强>结果:强>
2014-01-19 00:00:00.000 | 1915.74
2014-01-26 00:00:00.000 | 567.00
2014-02-02 00:00:00.000 | 1250.00
2014-02-09 00:00:00.000 | NULL
2014-02-16 00:00:00.000 | 300.00
2014-02-23 00:00:00.000 | NULL
2014-03-02 00:00:00.000 | NULL
2014-03-09 00:00:00.000 | NULL
NB:上述查询使用特殊构造进行日期比较,无论您的CreatedDate列是包含日期(仅限)还是日期和时间,都可以使用该构造。
col >= startDateAtMidnight AND
col < dayAfterEndDateAtMidnight
答案 1 :(得分:0)
这样的事情:
<Cfset datePlaceholder= now()/>
<!--- this would loop for 12 weeks --->
<Cfloop from="7*12" to="1" step="-7" index="stepper">
<cfquery...>
SELECT SUM(Amount)
FROM Transactions
WHERE (CreatedDate
BETWEEN #dateformat(datePlaceholder,'MM-DD-YYYY')#
AND #dateformat(dateAdd('d',stepper,datePlaceholder),'MM-DD-YYYY')#)
AND (Amount > 0)
</cfquery>
...do whatever you need to with this week of data
</cfloop>
Cavaets - 某些类型的日期字段包括时间(例如smalldatetime),因此您可能需要将00:00:00或23:59:59附加到它们。
您必须调试此代码 - 我没有运行它。
Cfquery是其中一个我更喜欢标签的可读性(以及从查询分析器或navicat或其他任何东西剪切和粘贴)。
答案 2 :(得分:0)
我会做与Mark相似的事情,但是使用参数化值。
<Cfset datePlaceholder= now()/>
<!--- this would loop for 12 weeks --->
<Cfloop from="7*12" to="1" step="-7" index="stepper">
<cfquery...>
DECLARE @datePlaceholder date = <cfqueryparam cfsqltype="CF_SQL_date" value="#datePlaceholder#">
DECLARE @stepper tinyint = <cfqueryparam cfsqltype="CF_SQL_tinyint" value="#stepper#">
SELECT SUM(Amount)
FROM Transactions
WHERE CreatedDate BETWEEN @placeholder AND DateAdd(d, @stepper, @placeholder)
AND (Amount > 0)
</cfquery>
...do whatever you need to with this week of data
</cfloop>
请注意,SQL中的DateAdd函数与ColdFusion中的DateAdd略有不同