如何在SQL语句中按日期范围过滤而没有时间组件

时间:2016-09-01 13:15:50

标签: sql-server

示例查询

SELECT * FROM orders WHERE New_ActualDate >= @fromdate AND New_ActualDate <= @todate

q.Parameters.AddWithValue("@fromdate", calFrom.SelectedDate);
q.Parameters.AddWithValue("@todate", calTo.SelectedDate);

当我检查它们的参数值时:

@fromdate =&#39; 01/08/2016 00:00:00&#39; @todate =&#39; 31/08/2016 00:00:00&#39;

我发现的问题是报告中缺少昨天(8月31日)的任何订单。

我是否还需要在此示例中设置时间?

3 个答案:

答案 0 :(得分:4)

&#34;技巧&#34;是使用明天的日期并将<=更改为<

SELECT * FROM orders WHERE New_ActualDate >= @fromdate AND New_ActualDate < @todatePlusOne

q.Parameters.AddWithValue("@fromdate", calFrom.SelectedDate);
q.Parameters.AddWithValue("@todatePlusOne", calTo.SelectedDate.AddDays(1));

请注意,建议不要使用@todate = 31/08/2016 23:59:59解决方法:您错过了23:59:5900:00:00之间发生的事情。试图获得正好小于00:00:00的一个最小单位的点是很难的,因为它取决于确切的数据类型,你必须考虑四舍五入。如果您对这些细节感兴趣,可以参考一篇关于该主题的博客文章:

答案 1 :(得分:0)

给出的答案将起作用,并且是处理组合日期/时间字段的好方法。但是,您(或其他读者)理解替代解决方案可能是值得的 - 为什么在您不需要时解决问题?

SQL Server支持date数据类型,它完全符合您的预期:它只存储日期,不存储时间戳。这有一些规模优势,也可以帮助您避免编写混乱的查询来解决时间戳问题。

如果New_ActualDate列只是一个日期,那么可以(并且我认为应该)使用date而不是datetime或{{1} }。然后,您可以将参数的日期部分传递给它,并且您的查询将按照您最初的希望工作。

答案 2 :(得分:0)

我认为BETWEEN语法很好而且干净。为了使用它,我们有一个名为.EndOfDay()的扩展名。

所以我可能会用以下方式写这个:

C#Extension(任何语言应该支持类似的东西)

public static DateTime EndOfDay(this DateTime dateTime)
        {
            return new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0, dateTime.Kind).AddDays(1).AddMinutes(-1);
        }

SQL声明

SELECT * 
FROM orders 
WHERE New_ActualDate BETWEEN @fromdate AND @todate

<强>参数

q.Parameters.AddWithValue("@fromdate", calFrom.SelectedDate);
q.Parameters.AddWithValue("@todate", calTo.SelectedDate.EndOfDay());