SQLSRV:如何在两个日期之间进行搜索并获取所有记录

时间:2013-05-29 23:09:19

标签: php sql-server sqlsrv

我正在使用PHP和SQLSRV for MSSQL 2008 r2。

我希望能做的是将两个日期输入两个输入框,并仅显示所需日期之间的记录,总订单数和总价值示例:

我想显示24/05/13和29/05/13之间有多少订单,所以我会得到2个订单的输出,总价值= 50.

也许这比我想象的要容易。我是PHP和SQLSRV的新手。实现这个的最佳方法是什么?

**Orders Table** 

OrderId CustomerID OrderDate   OrderValue 
1        1         2013-05-29  23.00
2        2         2013-05-26  23.00
3        2         2013-05-26  27.00
4        3         2013-05-24  23.00

** * ** * *** 修改 * ** * ** * ** * ** * ****

好的,多亏Shawn,我有一个起点。我把他的查询放到下面的演示脚本中,但它没有执行,我哪里出错?

Form.php

<form action="action.php" method="post" >
  <input name="StartDate" type="text"  id="StartDate" value="start"/>
  <input name="StartDate" type="text"  id="EndDate" value="end"/>
  <input type="submit" name="submit" >

  </form>

Action.php此页面返回SQL计算

<?php
include("connect.php");
?>
<?php
DECLARE @StartDate datetime
DECLARE @EndDate datetime
DECLARE @CustomerID int

SET @StartDate = '05/24/2013' /* FORM.StartDate */
SET @EndDate = '05/29/2013'   /* FORM.EndDate */
SET @CustomerID = 2           /* FORM.CustomerID */

/* Get the TotalOrderValue for All CustomerIDs */
$sql ="SELECT CustomerID, sum(OrderValue) AS TotalOrderValue
FROM Orders
WHERE OrderDate >= @StartDate
  AND OrderDate < dateAdd(d,1,@EndDate)
GROUP BY CustomerID
ORDER BY CustomerID";

$stmt = sqlsrv_query( $conn, $sql);
if( $stmt === false ) {
     die( print_r( sqlsrv_errors(), true));
}

$CustomerID = sqlsrv_get_field( $stmt, 0);
echo "$TotalOrderValue: ";
?>

1 个答案:

答案 0 :(得分:1)

我不明白为什么这个问题正在接受选票。该页面并没有完全回答克劳迪娅提出的问题。另外,给定的答案可能会导致一些意想不到的结果,特别是如果用户不关心时间,只关心日期。当没有给出时间时,SQL日期时间默认为“&lt; date&gt; 00:00:00.000”(并且日期舍入在第二个范围的千分之一中变得不稳定)。因此&lt; = 5/29/2013将在午夜之后排除所有5月29日(技术上所有发生在2013年5月29日00:00:00.001之后)。并且&gt; = 2013年5月24日将收到2013年5月23日发生的订单23:59:59.998。当你使用BETWEEN startDate和endDate(我个人讨厌)时也一样。

这一切都取决于您想要/需要的精度水平。对于大多数情况,.003秒不会是一个大问题。像下面这样的东西会起作用:

DECLARE @StartDate datetime
DECLARE @EndDate datetime
DECLARE @CustomerID int

SET @StartDate = '05/24/2013' /* FORM.StartDate */
SET @EndDate = '05/29/2013'   /* FORM.EndDate */
SET @CustomerID = 2           /* FORM.CustomerID */

/* Get the TotalOrderValue for Specific CustomerID */
SELECT sum(OrderValue) AS TotalOrderValue
FROM Orders
WHERE CustomerID = @CustomerID
  AND OrderDate >= @StartDate
  AND OrderDate < dateAdd(d,1,@EndDate)

/* Get the TotalOrderValue for All CustomerIDs */
SELECT CustomerID, sum(OrderValue) AS TotalOrderValue
FROM Orders
WHERE OrderDate >= @StartDate
  AND OrderDate < dateAdd(d,1,@EndDate)
GROUP BY CustomerID
ORDER BY CustomerID

首先,SELECT将允许您返回传入的特定CustomerID的TotalOrderValue。第二个SELECT将返回所有CustomerID。

同样,如果您需要高度的日期精确度,这个解决方案并不完美,因为您仍然可以获取在时间范围的毫秒边缘发生的订单。您必须稍微更改查询以检查日期和时间的各个部分。我认为最好的解决方案是要小心如何在前端存储日期。尽早确定您关心日期时间的精确度,并在插入/更新它们时对其进行格式化。如果您不需要精度,请切换到smalldatetime。这完全摆脱了秒。它使用较少的数据存储。

SQL中的日期很容易让人痛苦。你只需要知道你在查询中实际得到的是什么。

http://sqlfiddle.com/#!3/0947e/9/0 http://sqlfiddle.com/#!3/0947e/6

日期舍入:http://sqlfiddle.com/#!3/d41d8/14821/0