我有一个简单的预订系统。 ReservationObject是一个扁平结构,由StartDate,EndDate,Resource和其他属性组成。
我正在尝试获取资源使用情况的报告。对于此报告,我只是查询StartDate以查找具有报告查询范围的所有预留并计算它们。
示例SQL查询是..
"SELECT *
FROM RequestsQueueObjects
WHERE PODObjectID='" +cPOD.PODObjectID + "'
and StartDateTime >= '" + StartDate + "'
and StartDateTime <= '" + EndDate + "'";
我的设计存在问题。如果我的预订从2015年1月1日开始并于2015年1月15日结束,则不会显示在2015年1月1日至2015年1月7日的报告中
有没有办法让SQL查找两个日期之间的所有预留对象?
答案 0 :(得分:2)
修改强>
您想要检查日期范围是否重叠。请尝试以下方法:
"SELECT *
FROM RequestsQueueObjects
WHERE PODObjectID='" +cPOD.PODObjectID + "'
and StartDateTime <= '" + EndDate+ "'
and EndDateTime >= '" + StartDate + "'";
(与Steve参数化查询推荐相结合)
答案 1 :(得分:2)
您应该使用以下逻辑的参数化查询:
"SELECT *
FROM RequestsQueueObjects
WHERE PODObjectID= @PODObjectID
and ((StartDateTime >= @StartDate and EndDateTime <= @EndDate)
OR (StartDateTime <= @StartDate and EndDateTime >= @StartDate)
OR (StartDateTime <= @EndDate and EndDateTime >= @EndDate)
OR (StartDateTime <= @StartDate and EndDateTime >= @EndDate))
";
虽然以上解决方案有效,但由于Thomas Haratyk建议的链接,可以简化如下。
http://logic-and-trick.com/Blog/The-Overlapping-Date-Range-Test
"SELECT *
FROM RequestsQueueObjects
WHERE PODObjectID= @PODObjectID
and EndDateTime >= @StartDate and StartDateTime <= @EndDate
";
答案 2 :(得分:1)
使用参数化查询,让数据库引擎确定您通过的日期 在您的代码中,您可以在逗号之间编写日期,这样数据库引擎就可以根据其本地化规则进行翻译。当然,这可能导致完全错误的结果或丢失记录
DateTime startDate = new DateTime(2015, 2, 1);
DateTime endDate = new DateTime(2015, 7, 1, 23, 59, 59); // add time to Include all day
string cmdText = @"SELECT * FROM RequestsQueueObjects
WHERE PODObjectID = @id
and StartDateTime >= @start
and StartDateTime <= @end";
using(SqlConnection cn = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(cmdText, cn))
{
cn.Open();
cmd.Parameters.Add("@id", cPOD.PODObjectID);
cmd.Parameters.Add("@start", StartDate);
cmd.Parameters.Add("@start", EndDate);
using(SqlDataReader reader = cmd.ExecuteReader())
{
....
}
}