mysql date compare query gives wrong results - php

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'))

Related

SQL query different results between workbench and PHP script in the same date range

I have a PHP script that helps me to make some financial reports like capital, profits, total sold item, total item in store between 2 dates:
$result[] = 0;
$res[] = 0;
$fetchStat[]=0;
if(isset($_POST['generate_capital']))
{
$from_d = $_POST['from_d'];
$to_d = $_POST['to_d'];
$stat = "SELECT sum(sell_quantity*(sell_price-init_price)) AS 'rebeh', sum(init_price*(quantity-sell_quantity)) AS 'capital', sum(sell_price*sell_quantity) AS 'profits', sum(quantity) AS 'total_item', sum(sell_quantity) AS 'total_sell' FROM purchases WHERE date_now BETWEEN :d1 AND :d2";
$stmtStat = $conn->prepare($stat);
$stmtStat->bindValue(':d1', $from_d);
$stmtStat->bindValue(':d2', $to_d);
$execStat = $stmtStat->execute();
$fetchStat= $stmtStat->fetchAll();
}
Now, the same query in MySQL workbench will give me a specific result:
SELECT sum(sell_quantity*(sell_price-init_price)) AS 'rebeh',
sum(init_price*(quantity-sell_quantity)) AS 'capital', sum(sell_price*sell_quantity) AS 'profits',
sum(quantity) AS 'total_item',
sum(sell_quantity) AS 'total_sell'
FROM purchases WHERE date_now BETWEEN '2016-02-02' AND '2016-05-09'
The result is:
And the same query in the PHP script with the same date range will give me other values:
I've changed the Arabic keywords with English ones so you can see the difference.
Any help is appreciated.
EDIT: Adding var_dump result for 2 dates
As it stands, it appears that the most likely cause is that your date formats have the month and day in the wrong order, for the 2nd of February, that doesn't matter, but for the 9th of May, it would become the 5th of September.
Now, the reason that the data for the 9th of May isn't included when you run the query directly is because a date is actually midnight on that date, making it exclusive of that date when it comes at the end of a between.
It's possible there is something else, so if this doesn't work, try echoing out all your values at every point, until you know exactly what is being run, and it should become clear.
To clarify, when using '/' in a date, MySQL uses the following format:
'%d/%m/%Y'
Which would explain why it works if you enter a string into your text box.

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

how can load the day in {html_select_date} from the day in mysql

i need to display the drop down when the day is come from mysql
my query is
select doj from user_detatils where user_id='2'
i use the html_select_date for the drop down option
The code is below
{html_select_date start_year=1970 month_format="%b" field_order="dmy"
field_array="date" prefix="" day_id="dd" month_id="mm" year_id="yy"
year_empty="Year" month_empty="Month" day_empty="Day" }
if the table return the doj that date will be select in the drop down
else the drop down didn't select any value
Following up on how can change the numeric to month in words.
{html_select_date} explains the time argument. granted, it does a poor job in explaining that time=null will lead to "no date selected" and anything else that evaluates falsy (false, 0, "", …) will select the "current date".
So your PHP should check if the database has a valid date in doj, otherwise set that variable to null.

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.

searching between dates in MYSQL in this format 03/17/10.11:22:45

I have a script that automatically populates a mysql database with data every hour. It populates the date field like 03/17/10.12:34:11 and so on.
I'm working on pulling data based on 1 day at a time from a search script.
If i use
SELECT *
FROM call_logs
WHERE call_initiated between '03/17/10.12:00:00' and '03/17/10.13:00:00'
it works, but when I try to add the rest of the search params, it ignores the call_initiated field.
SELECT *
FROM call_logs
WHERE caller_dn = '2x9xxx0000' OR called_dn = '2x9xxx0000'
AND call_initiated between '03/17/10.12:00:00' and '03/17/10.13:00:00'
^-- I x'd out a couple of the numbers. I've also tried without the between function, and used >= <= to pull the records, but have the same results. Im sure its an oversight, thanks in advance.
try using parentheses around your OR statement
... where (caller_dn='2x9xxx0000' OR called_dn='2x9xxx0000') AND call_initiated between '03/17/10.12:00:00' and '03/17/10.13:00:00'
use the IN operator instead of OR
... where caller_dn IN('2x9xxx0000','2y9yyyy000') AND call_initiated between '03/17/10.12:00:00' and '03/17/10.13:00:00'
The OR statement is more than likely the issue, since OR evaluates the left side, sees that its true, it doesn't care what is on the right site, because as long as one of the statements is true, it considiers the entire statement to be true.
Read up on the OR operator at the MYSQL page
Your Statement should look like
SELECT * FROM `call_logs` WHERE (caller_dn='2x9xxx0000' OR called_dn='2x9xxx0000') AND call_initiated BETWEEN '03/17/10.12:00:00' and '03/17/10.13:00:00';

Categories