andrewxt andrewxt - 6 months ago 10
PHP Question

SQL pulling data based on date

I have a database full of store information and personal transactions. I have two webpages. One takes user input for the store name and runs a query pulling all transaction info for that store. I have another page almost identical that takes input for a start date and an end date and then runs a query for transactions between that date. The one for the store name works perfectly, but the one for the date doesn't display anything. I am still learning html/php/sql but I know exactly how the first page works so I cannot see why the same doesn't work for the second. If someone could help me, I'd appreciate it.

Here is my first page for the store name search that works.

<?php

$transaction = $_REQUEST["StoreName"];

require_once 'login.php';

$connection = mysqli_connect(
$db_hostname, $db_username,
$db_password, $db_database);



$sql = "SELECT * FROM PURCHASE WHERE StoreName LIKE '%".$transaction."%'";
$result = $connection->query($sql);

?>

Purchases Made From <?php echo $transaction ?>
<table border="2" style="width:100%">
<tr>
<th width="15%">Item Name</th>
<th width="15%">Item Price</th>
<th width="15%">Purchase Time</th>
<th width="15%">Purchase Date</th>
<th width="15%">Category</th>
<th width="15%">Rating</th>
</tr>
</table>
<?php
if($result->num_rows > 0){
// output data of each row
while($rows = $result->fetch_assoc()){ ?>
<table border="2" style="width:100%">
<tr>
<td width="15%"><?php echo $rows['ItemName']; ?></td>
<td width="15%"><?php echo $rows['ItemPrice']; ?></td>
<td width="15%"><?php echo $rows['PurchaseTime']; ?></td>
<td width="15%"><?php echo $rows['PurchaseDate']; ?></td>
<td width="15%"><?php echo $rows['PurchaseCategory']; ?></td>
<td width="15%"><?php echo $rows['Rating']; ?></td>
</tr>
<?php
}
}
?>


And here is the page for the date search that returns no data.

<?php

$startDate = $_REQUEST["StartDate"];
$endDate = $_REQUEST["EndDate"];

require_once 'login.php';

$connection = mysqli_connect(
$db_hostname, $db_username,
$db_password, $db_database);



$sql = "SELECT * FROM PURCHASE WHERE PurchaseDate BETWEEN '%".$startDate."%' and '%".$endDate."%'";
$result = $connection->query($sql);

?>

Purchases Made Between <?php echo $startDate ?> and <?php echo $endDate ?>
<table border="2" style="width:100%">
<tr>
<th width="15%">Item Name</th>
<th width="15%">Item Price</th>
<th width="15%">Purchase Time</th>
<th width="15%">Purchase Date</th>
<th width="15%">Category</th>
<th width="15%">Rating</th>
</tr>
</table>
<?php
if($result->num_rows > 0){
// output data of each row
while($rows = $result->fetch_assoc()){ ?>
<table border="2" style="width:100%">
<tr>
<td width="15%"><?php echo $rows['ItemName']; ?></td>
<td width="15%"><?php echo $rows['ItemPrice']; ?></td>
<td width="15%"><?php echo $rows['PurchaseTime']; ?></td>
<td width="15%"><?php echo $rows['PurchaseDate']; ?></td>
<td width="15%"><?php echo $rows['PurchaseCategory']; ?></td>
<td width="15%"><?php echo $rows['Rating']; ?></td>
</tr>
<?php
}
}
?>


Obviously the initial search pages that link to both of these output pages differ a bit more but I can confirm that the date output page is receiving the correct dates from the search page.

EDIT: Here is the search page for the date.

<!DOCTYPE html>
<html>
<head>
<title>Output 2</title>
</head>
<body>
<h1>Required Output 2</h1>
<h2>Transaction Search By Date</h2>
<br/>
<br/>

<form action="outputout2.php" method="get">
Start Date: <input type="date" name="StartDate">
End Date: <input type="date" name="EndDate">
<input name="Add Merchant" type="submit" value="Search">
</form>;

</body>
</html>

Answer

This sort of problem is usually the result of misformatted dates.

Your query, if I'm reading it right, says this when you've finished assembling it in php and sent it to the SQL server:

 SELECT *
   FROM PURCHASE                   --wrong!
  WHERE PurchaseDate BETWEEN '%5/1/2016%' and '%5/8/2016%'

This is not going to work.

For one thing, the % signs only work with the LIKE operator, not on equality and inequality operators.

For another thing, different makes and models of database server software use differently formatted date strings. MySQL and SQL Server will work fine with string formats like 2016-05-01. But you have to look up the appropriate ways of doing this for the kind of SQL software product you are using. This kind of stuff is not very vendor-portable.

Third: your PurchaseDate column in your table needs to have a date-like datatype for this kind of thing to work.

Fourth: if your PurchaseDate items are timestamps -- that is, if that have both dates and times -- you can't reliably use the BETWEEN operator. Here's why: Suppose you have a value of 2016-05-08 11:50:00 When you compare that to an end date 2016-05-08, it lies beyond the end date. So, what you really need is this:

 WHERE PurchaseDate >= '2016-05-01'
   AND PurchaseDate <  '2016-05-09' -- the day AFTER your end date

That construct performs the same as BETWEEN and doesn't screw up the last days' data.

Edit so it's MySQL you're using.

Workbench is a client program. So is PHP. The server is MySQL. When you do an operation like

     DateColumn < 'string constant'

MySQL implicitly converts the string constant to a date. If the format of the string constant is close enough to ISO 8601 for the server to figure out what it means, it will convert it. 2016-12-13 is exactly right. 2016-5-31 is close enough for MySQL, and so is 2016-5-5. 2016/12/31 doesn't work. Neither does 5/5/16.

Germane to your question is this: MySQL cannot convert %2016-5-5% (with the percent signs) to a date.

When MySQL can't convert a date, it comes up with NULL. Comparisons with NULL values are weird. And, in the immortal words of Hunter S. Thompson, "when the going gets weird, the weird turn pro". NULL weirdness is probably the root cause of your empty result set in the query you showed.

Comments