【问题标题】:SQLSRV: How to search between two dates and get all recordsSQLSRV:如何在两个日期之间搜索并获取所有记录
【发布时间】:2013-05-29 23:09:19
【问题描述】:

我将 PHP 与 SQLSRV 一起用于 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

*********编辑************** ***

好的,多亏了肖恩,我有了一个起点。我已经将他的查询放入下面的演示脚本中,但是它没有执行,我哪里出错了?

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: ";
?>

【问题讨论】:

  • 谢谢,我看看这个。
  • 在您的表单中,它们都被命名为 StartDate。当您将查询放入您的 PHP 代码时,您可以删除 DECLARE 和 SET 语句,只需从表单中动态输入 StartDate 和 EndDate。上面的查询将为您提供所有客户。如果您只需要一个,您可能应该只查询一个。您的 OrderDate 是存储为 DATE 数据类型,还是只是存储在不同数据类型中的日期文本?

标签: php sql-server sqlsrv


【解决方案1】:

我不明白为什么这个问题会遭到反对。该页面并没有完全回答 Claudia 提出的问题。另外,给出的答案可能会导致一些意想不到的结果,特别是如果用户不关心时间,只关心日期。当没有给出时间时,SQL 日期时间默认为“ 00:00:00.000”(日期舍入在千分之一秒范围内变得不稳定)。所以 = 5/24/2013 将接收 2013 年 5 月 23 日 23:59:59.998 发生的订单。当您使用 BETWEEN startDate 和 endDate (我个人讨厌)时也是如此。

这完全取决于您想要/需要的精度水平。在大多数情况下,0.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

【讨论】:

  • 非常感谢,肖恩。我稍后会实现这个,让你知道我是怎么做到的。
猜你喜欢
  • 2016-08-04
  • 2020-05-12
  • 2019-03-14
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
相关资源
最近更新 更多