mssql filter by date range

时间:2015-05-18 18:03:17

标签: sql sql-server tsql

I'm writing a little query that builds a count of rows per month&year, to mimic the behavior you'd see in google analytics.

this is my query:

USE MyDatabase;

SELECT
    COUNT(*) AS Rows,
    DATENAME(mm, OpenDate) AS Month,
    DATENAME(yyyy, OpenDate) AS Year
FROM MyTable
WHERE Priority = 1
GROUP BY DATENAME(mm, OpenDate), DATENAME(yyyy, OpenDate)
ORDER BY Year, Month DESC;

I'm unclear as to how I'd apply a date range filter in this query.

  1. Should I use HAVING or WHERE?
  2. Do I need to use a fully formed datetime string for my vars? or do I filter by year and months separately since I've got those columns?

2 个答案:

答案 0 :(得分:3)

或者,您也可以将日期时间字段(OpenDate)转换为日期,并执行以下操作:

USE MyDatabase;

DECLARE @StartDate DATE
    ,@EndDate DATE

SET @StartDate = '2015-05-01'
SET @EndDate = '2015-05-30'

BEGIN
    SELECT COUNT(*) AS Rows
        ,DATENAME(mm, OpenDate) AS Month
        ,DATENAME(yyyy, OpenDate) AS Year
    FROM MyTable
    WHERE Priority = 1
        AND CAST(OpenDate AS DATE) BETWEEN @StartDate
            AND @EndDate
    GROUP BY DATENAME(mm, OpenDate)
            ,DATENAME(yyyy, OpenDate)
    ORDER BY Year,Month DESC;
END

VS HAVING?

WHERE子句在执行聚合之前限制数据,而HAVING子句在执行聚合之后限制数据。

使用WHERE子句总是更好,因为不需要让计算机计算聚合然后将其过滤掉。

答案 1 :(得分:2)

正如@bluefeet所说,这通常应该起作用:

WHERE OpenDate >= @Date1 and OpenDate <= @Date2
  

我应该使用HAVING还是WHERE?

WHERE。

HAVING用于在分组和聚合后过滤,所以一个好的经验法则是你只需要在需要引用像HAVING COUNT(*) > 10这样的聚合函数时使用它。另外,请记住HAVING子句中的每个字段也必须位于GROUP BY或聚合中。它可以在这里工作,但除非你知道你需要它,否则避免HAVING是更好的逻辑。通常,您可以越早过滤数据集中的内容,处理的速度越快,GROUP BY之前的WHERE进程。

  

我是否需要为我的vars使用完全形成的日期时间字符串?或者我分开过滤年份和月份,因为我有这些列?

制作完整日期或日期时间通常最简单。你将在某个时刻跨越年界,如果你不这样做,那将是一个巨大的痛苦。如果你想要2014年11月到2015年1月怎么办?或2013年5月至2015年5月?

您唯一需要决定的是,您是否或如何汇总分数月份。那么,该应用程序是否允许用户说他们想要2014年6月23日到2014年7月13日?

如果他们这样做了,你会退回吗,或者你是否在6月和7月归还了所有内容而忽略了他们选择了特定日期的事实?

如果是前者,那么@ bluefeet的回答很好:

WHERE OpenDate >= @Date1 and OpenDate <= @Date2

如果没有,那么您可能需要修改日期标准。通常,你会想说:

WHERE OpenDate >= {First Date Of Date1's Month}
    AND OpenDate < {First Date of Month After Date2 Month}

因此,如果您想从2014年6月23日到2015年1月13日,那么看起来像是:

WHERE OpenDate >= '2014-06-01' 
    AND OpenDate < '2015-01-01'

这样做意味着您不必担心一个月内有多少天。在将应用程序提交到查询引擎之前,通常可以在应用程序中处理日期数学,但可以使用CAST(),YEAR(),MONTH()和DATEADD()在SQL中完成。