简体   繁体   English

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

[英]SQLSRV: How to search between two dates and get all records

I'm using PHP with SQLSRV for MSSQL 2008 r2. 我正在将PHP与SQLSRV一起用于MSSQL 2008 r2。

What I want to be able do, is to input two dates into two input boxes, and show only records between desired dates, with total count of orders and total value example: 我想要做的是在两个输入框中输入两个日期,并仅显示所需日期之间的记录,其中包括订单总数和总价值示例:

I would like to show how many orders were placed between 24/05/13 and 29/05/13, so I would get an output along the lines of 2 orders were placed, total value = 50. 我想显示在2013年5月24日至2013年5月29日之间下了多少个订单,因此我将沿着放置2个订单的行获得输出,总价值= 50。

Maybe this is easier than I think. 也许这比我想的要容易。 I'm new to PHP and SQLSRV. 我是PHP和SQLSRV的新手。 What is the best way to implement this? 实现此目的的最佳方法是什么?

**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

** * ** * *** EDIT * ** * ** * ** * ** * **** ** * ** * *** 编辑 * ** * ** * ** * ** * ****

Okay, thanks to Shawn, I have a starting point. 好的,感谢肖恩,我有一个起点。 I've put his query into the following demo script, however it's not executing, where am I going wrong? 我已将他的查询放入以下演示脚本中,但是未执行,我在哪里出错?

Form.php 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 This page returns the SQL calculation 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: ";
?>

I don't understand why this question is receiving down-votes. 我不明白为什么这个问题得到了反对。 That page doesn't quite answer the question Claudia is asking. 该页面并不能完全回答Claudia提出的问题。 Plus that given answer can lead to some unexpected results, especially if the user doesn't care about the time, just the date. 加上给出的答案可能会导致一些出乎意料的结果,特别是如果用户不在乎时间,只在乎日期。 When a time isn't given, a SQL datetime defaults to "< date > 00:00:00.000" (and date rounding gets wonky in the thousandths of a second ranges). 如果未指定时间,则SQL日期时间默认为“ <date> 00:00:00.000”(日期舍入会在千分之一秒的范围内发生变化)。 So <= 5/29/2013 would exclude all of May 29 after midnight (technically everything that happened after 5/29/2013 00:00:00.001). 因此<= 5/29/2013将排除午夜之后的5月29日(从技术上讲,是5/29/2013 00:00:00.001之后发生的所有事件)。 And >= 5/24/2013 would pick up orders that happened on 5/23/2013 23:59:59.998. 并且> = 5/24/2013会提取2013年5月23日23:59:59.998发生的订单。 Same thing when you use a BETWEEN startDate and endDate (which I personally hate). 当您使用BETWEEN startDate和endDate(我个人讨厌)时,也是一样。

It all depends on the level of precision you want/need. 这完全取决于您想要/需要的精度水平。 For most situations, .003 seconds isn't going to be a big deal. 在大多数情况下,0.003秒并不是什么大问题。 Something like below would work: 像下面这样的东西会工作:

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

First SELECT will allow you to return the TotalOrderValue for the specific CustomerID you pass in. Second SELECT will return for all CustomerIDs. 第一个SELECT将允许您为传入的特定客户ID返回TotalOrderValue。第二个SELECT将为所有客户ID返回。

Again, this solution isn't perfect if you need a high degree of date precision, because you'd still pick up orders that happened on the millisecond edges of your timeframe. 同样,如果您需要高度的日期精度,则此解决方案也不完美,因为您仍然可以拾取在时间范围的毫秒范围内发生的订单。 You'd have to change up your query a little bit to check the individual pieces of the date and time. 您必须稍微修改一下查询来检查日期和时间的各个部分。 I think the best solution is to just be careful how you store dates on the front end. 我认为最好的解决方案是小心在前端存储日期。 Decide early how much you care about the precision of the datetimes and format them when you insert/update them. 尽早确定您对日期时间的精度有多大的关注,并在插入/更新日期格式时对其进行格式化。 If you don't need the precision, switch down to a smalldatetime. 如果不需要精度,请切换到较小的日期时间。 That gets rid of the seconds, altogether. 完全摆脱了秒。 And it uses less data storage. 而且它使用更少的数据存储。

Dates in SQL can easily be a pain. SQL中的日期很容易让人感到痛苦。 You just have to know what it is you're actually getting back in a query. 您只需要知道查询返回的内容是什么。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM