SQL query using PHP not recognizing results between dates properly - php

These expressions works perfectly:
$sql = "SELECT * FROM TABLE_SUITE_INSPECTION
WHERE QA_DATE = '$s_date'; returns the data for the requested date
$sql = "SELECT * FROM TABLE_SUITE_INSPECTION
WHERE QA_DATE = '$s_date' OR QA_DATE='$e_date'"; returns the data for the two required dates.
I can't figure out the reason for this statement not to work:
$sql = "SELECT * FROM TABLE_SUITE_INSPECTION
WHERE QA_DATE BETWEEN '$s_date' AND '$e_date'";
The SQL database has the QA_DATE as VARCHAR.
The data returned is always incomplete or with no results at all.
Example: The database has data for the following dates:
2/4/18
2/5/18
2/7/18
2/8/18
2/9/18
2/11/18
2/15/18
2/16/18
2/18/18
The results for s_date=2/4/18 and e_date=2/18/18 are none.
The result for s_date=2/4/18 and e_date=2/4/18 is correct.
The result for s_date=2/18/18 and e_date=2/18/18 is correct.
The results for s_date=2/4/18 and e_date=2/5/18 are correct.
The results for s_date=2/4/18 and e_date=2/7/18 are correct.
The results for s_date=2/4/18 and e_date=2/8/18 are correct.
The results for s_date=2/4/18 and e_date=2/9/18 are correct.
The results for s_date=2/4/18 and e_date=2/11/18 are none.
The result for s_date=2/11/18 and e_date=2/11/18 is correct.
The results for s_date=Any date and e_date=2/9/18 are correct.
Why is the query not picking up results for dates greater than 2/11/18?
Thanks for any help

Since the database column is a varchar, the data is being compared alphabetically. Alphabetically, 2/11/18 is the earliest value, so that's why you're seeing the results you're seeing. This is one reason why it's always best to use a date column type for dates.
You can probably make it work using https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_str-to-date or similar. But if you can change the data set that would be a much better solution.

Related

Different Mysql date Results On website and in PHPmyadmin

I wants to select rows which are less than with today date.
In database my date column is saving data in unix time stamp.
I am running on following query with php and mysql. (this query should show 1 row as i have 1 result in the database, but it is showing two rows.)
SELECT * from products where seller_id ='1' and FROM_UNIXTIME(marketing_end_date,'%Y-%m-%d') < CURRENT_DATE();
But when i run above query in phpmyadmin it retrun one row( my desired result).
Here is my code which is reading data from mysql.
function get_sellerenddateproducts($admin,$seller_id,$limit_per_page,$start_index){
$this->db->select('*');
$this->db->where(array('seller_id' => $seller_id));
$this->db->where("FROM_UNIXTIME(marketing_end_date,'%Y-%m-%d') <","CURRENT_DATE()");
$this->db->limit($limit_per_page, $start_index);
$this->db->order_by('id','desc');
$query = $this->db->from($this->_table_name)->get();
$arr = $query->result_array();
//echo $this->db->last_query(); die();
return $arr;
}
Question
Why same query show different results ? How to get correct results?
MySQL actually stores datetime data type fields internally as UTC.
However, PhpMyAdmin shows you the dates using the server default time.
Use this line to detect TimeZone of your MySQL Server:
SELECT ##system_time_zone;
For example, try adding this line before PhpMyAdmin SQL statement:
Set time_zone = '+00:00';
This sets timezone to GMT/UTC, so that any further operations will use GMT.
Let me know if they return same result now :)
I resolve my issue like below.
I create a variable like this.
$todaydate = date('Y-m-d');
and change my query from
$this->db->where("FROM_UNIXTIME(marketing_end_date,'%Y-%m-%d') <","CURRENT_DATE()");
to this
$this->db->where("FROM_UNIXTIME(marketing_end_date,'%Y-%m-%d') <",$todaydate);
then it gives me correct result.

mysql date compare query gives wrong results

I have this table and the query I give returns wrong results, I am not sure where the problem is
the date comparisons
or
structure of the query
The query if not clear in the image is :
select * from transact where item_code='msft234' or item_code='hp550x' and transact_date>=STR_TO_DATE('06-07-2013','%d-%m-%Y') and transact_date<=STR_TO_DATE('12-07-2013','%d-%m-%Y')
Your query employs a wrong syntax:
WHERE item_code='msft234' OR item_code='hp550x'
AND transact_date>=STR_TO_DATE('06-07-2013','%d-%m-%Y')
AND transact_date<=STR_TO_DATE('12-07-2013','%d-%m-%Y')
since AND priority is higher, it means that it will be satisfied if either you get hp550x in that date interval, or you get msft234 regardless of the date.
You have to put the OR'ed item codes in parentheses: (item_code='..' OR item_code='..' OR ..), or use IN: e.g.
SELECT * FROM transact
WHERE item_code IN ('msft234', 'hp550x')
AND transact_date BETWEEN
STR_TO_DATE('06-07-2013','%d-%m-%Y')
AND
STR_TO_DATE('12-07-2013','%d-%m-%Y')
Also, depending on the type you select for the date fields, consider that for a date to be "less or equal than 12-07-2013", it has to be less or equal than 12-07-2013 at 00:00, i.e., almost the latest date that will match is 11-07-2013 at 23:59:59.
So "less or equal than 12-07" will actually never select any row from 12-07-2013 unless it happens to have been inserted exactly at midnight.
If you insert rows by only specifying the date, then it will very probably work - the rows will be input at midnight and matched at midnight. But if (some) rows are entered with the full datetime, e.g. because they're type datetime and updated with NOW(), then they will not match.
put the item conditions between ()
(ítem_code = 'msft234' OR ítem_code = 'hp550x') AND transact_date>=STR_TO_DATE('06-07-2013','%d-%m-%Y') and transact_date<=STR_TO_DATE('12-07-2013','%d-%m-%Y')
(ítem_code = 'msft234' OR ítem_code = 'hp550x') AND transact_date BETWEEN STR_TO_DATE('06-07-2013','%d-%m-%Y') and STR_TO_DATE('12-07-2013','%d-%m-%Y')
For security I will put with 2 ()
(ítem_code = 'msft234' OR ítem_code = 'hp550x') AND (transact_date BETWEEN STR_TO_DATE('06-07-2013','%d-%m-%Y') and STR_TO_DATE('12-07-2013','%d-%m-%Y'))

How to get the number of results MySql would have returned without limit?

I have a table with a lot of data, so I retrieve it and display it one page at a time (my request is lengthy so there is no way I run it on the entire table).
But I would like to paginate the results, so I need to know what is the total number of elements in my table.
If I perform a COUNT(*) in the same request, I get the number of selected elements (in my case, 10).
If I perform a COUNT(*) on my table in a second request, the result might be wrong because of the where, join and having clauses in my main query.
What is the cleanest way to:
Retrieve the data
Know the maximum number of elements in my table for this specific request
One solution seems to be using the Mysql function FOUND_ROWS :
I tried this, as mysql_query performs one query at a time: (taken here)
$query = 'SELECT SQL_CALC_FOUND_ROWS * FROM Users';
$result = mysql_query($query);
// fetching the results ...
$query = 'SELECT FOUND_ROWS()';
$ result = mysql_query($query);
// debug
while ($row = mysql_fetch_row($result)) {
print_r($row);
}
And I got an array with 0 results:
Array ( [0] => 0 )
Whereas my query does returns results.
What is wrong with my approach ? Do you have a better solution ?
Set mysql.trace_mode to Off if it is On.
ini_set('mysql.trace_mode','Off'); may also work depending on your host configuration if you cannot edit my.cnf
If that doesn't make the code you posted above work, then you will need to run the query again without LIMIT and count it that way.
The code above works fine. I wasn't opening the connection correctly.
Output is :
Array ( [0] => 10976 )
I am still interested for an other way to do it, especially something that is not mysql dependent.

Filtering by date range in SQL query

I am unable to get the following code to work:
// dd/mm/yyyy for dates in SQL queries
$todayforw = date('d/m/Y');
$aweekago = date('d/m/Y', time() - 604800);
$week_e_check = mysql_query("SELECT * FROM earningslog WHERE user_id = '".$info['id']."' WHERE day >='".$aweekago."' AND day <'".$todayforw."'");
while ($week_e_info = mysql_fetch_array($week_e_check)) {
$week_e = $week_e + $week_e_info['user_earnings_amnt'];
}
The query returns zero rows, however, it should be returning data that matches the criteria.
Check your date format:
Should be:
YYYY-mm-dd HH:mm:ss
E.G.
2012-01-01 00:00:00 (January 1, 2012 at midnight local time)
Other date formats MAY work, but the best way to go about it is to use the same format that MySQL uses when they display the date, that's the only way I know that works every time.
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
Also your syntax is incorrect, you have two wheres, you should use AND.
Take a closer look at your query:
SELECT * FROM earningslog WHERE user_id = '".$info['id']."' WHERE day >='".$aweekago."' AND day <'".$todayforw."'"
Your Where clause appears twice.
Two things to think about - when you are selecting data, try and stay away from select * - you may get unexpected results of the table is ever modified.
Second, try and create the query as a parameterized query, instead of injecting the parameters directly into the where clause. By directly injecting your criteria the way you have, you are opening yourself up to a SQL injection attack.
By turning it into a parameterized query, you get the side benefit of being able to debug the queries directly against the database, reducing the amount of effort needed to copy it from a query tool into your code.
Your issue appears to be with your query syntax. You are stating WHERE twice, whereas you should only state it once and then use the AND or OR operators for further criteria. I would also suggest that you either move your statement into a variable or use die() to assist with debugging.
$week_e_check = mysql_query("SELECT * FROM earningslog WHERE user_id = '".$info['id']."' AND day >='".$aweekago."' AND day <'".$todayforw."'") or die(mysql_error());
In addition, you should not be using the mysql extension as use of this extension is discouraged. Instead, use the MySQLi or PDO_MySQL extension. Using one of these alternative extensions will help serve as the first step in preventing SQL injection. I would also suggest that you avoid using * and specify the column names to be returned instead.
Using PDO:
<?php
/* Execute a prepared statement by passing an array of values */
$sth = $dbh->prepare('SELECT * FROM earningslog WHERE user_id = ? AND day >= ? AND day < ?');
$sth->execute(array($info['id'], $aweekago, $todayforw));
$results = $sth->fetchAll();
?>
Try change the format of your strings from from d/m/Y to Y-m-d.
MySQL might be expecting it year first. In which case it could be doing the wrong thing with d/m/Y.
Also don't use the WHERE clause twice. Instead, combine conditions using AND, eg:
WHERE user_id = '".$info['id']."'
AND day >='".$aweekago."'
AND day <'".$todayforw."'
By the way, you can also try saying WHERE day BETWEEN ".$aweekago." AND ".$todayforw.", which might be easier syntax to read (as long as you change $todayforw to be the day before).

MySQL query with date ranges returning no results

So I am doing this query from PHP, and here listerally the exact query string:
SELECT * FROM `pdem_timesheet`.`tblMasterTimesheets` WHERE
`pdem_timesheet`.`tblMasterTimesheets`.`username` = 'pdem' AND
`pdem_timesheet`.`tblMasterTimesheets`.`date` >= '2012-05-09' AND
`pdem_timesheet`.`tblMasterTimesheets`.`date` <= '2012-05-15' ORDER BY
`pdem_timesheet`.`tblMasterTimesheets`.`date` ASC
It looks like it should be correct to me (more-or-less copying it from previous code I used that DOES work). But when I run the query, the results are empty.
If I change the query to not be a date range, but just a single day:
SELECT * FROM .... WHERE ...`date` = '2012-06-12' ....
it works just fine, returns the one result that it should.
I have tried using the between keyword:
SELECT * FROM ... WHERE ...`date` BETWEEN [start] [end]
but it still returns nothing...
Any ideas how to get this query to return a result?
===ANSWER===
When you go:
var curr_date = now.getDate();
var curr_month = now.getMonth();
var curr_year = now.getFullYear();
it returns the month - 1 for some reason. So if now's month is 6, now.getMonth() will return 5...Just need to add 1 in the query (wish I saw this sooner)
Your query seems to be working for me.
See demo.
Query I have is
SELECT * FROM tblMasterTimesheets
WHERE
username='pdem'
AND
date >= '2012-05-09' AND
date <= '2012-05-15'
ORDER BY date ASC
I assume, username is of type varchar and date is of type timestamp or datetime.
Similar to Fahim Parkar, here is an example of your query working with the use of the BETWEEN syntax: http://sqlfiddle.com/#!2/0fcb5/4
It sounds like your user pdem does not exist.
Make sure that:
There is in fact a result which should be returned when using your
given criteria. Make sure the DD-MM-YYYY syntax is correct and make sure you know which month is which number (may is 05, june is 06)
That the datatype of the column date is of a date
type, not a generic text/varchar type. You cannot compare varchar with >= like that (not the way you want, at least. Only works on date types)
As Fahim said, your code is correct. It must be something within the table which is causing your issues.

Categories