简体   繁体   中英

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

I'm using PHP with SQLSRV for 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.

Maybe this is easier than I think. I'm new to PHP and 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 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

<?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. 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). So <= 5/29/2013 would exclude all of May 29 after midnight (technically everything that happened after 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. Same thing when you use a BETWEEN startDate and endDate (which I personally hate).

It all depends on the level of precision you want/need. For most situations, .003 seconds isn't going to be a big deal. 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.

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

Date Rounding: http://sqlfiddle.com/#!3/d41d8/14821/0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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