使用ColdFusion循环更改数据库查询过滤器

时间:2014-10-24 19:39:21

标签: sql coldfusion

我有一张包含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>

这可能吗?

3 个答案:

答案 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略有不同