I have a table with some datetime columns. I need to be able to select the rows between two datetimes on the same column.
For example:
SELECT *
FROM `t_punchcards`
WHERE UserID = 'root' AND
PunchInTime > CAST('01-01-2015 00:00:00' AS DATETIME) AND
PunchInTime < CAST('03-06-2015 23:59:59' AS DATETIME);
For some strange reason, this yields no results. I have tried using BETWEEN, I've tried not casting to datetime from string (just use a raw string), I've tried <= >=. I'm very lost.
As a sidenote, removing the second constraint (AND PunchInTime < CAST('03-06-2015 23:59:59' AS DATETIME); WILL in fact yield results. Are you not allowed to do a comparison against the same column in the same query?
Here's an example of the table:
UserID(varchar) PunchInTime(datetime) PunchOutTime(datetime)
root 01-01-2015 8:02:31 01-01-2015 12:35:51
Just write this logic as:
WHERE UserID = 'root' AND
PunchInTime > DATE('2015-01-01') AND
PunchInTime < DATE('2015-03-07')
Note that I removed the time component from the second value. This is a cleaner way of making the comparison, unless you really want to treat the last few milliseconds of a day differently from the rest of the time during the day.
Note: If you are not using MySQL or you want more compliant code, the following works in more databases:
WHERE UserID = 'root' AND
PunchInTime > CAST('2015-01-01' as DATETIME) AND
PunchInTime < CAST('2015-03-07' as DATETIME)
Related
I was trying to make a SQL statement in PHP, to convert a string into a time(6). But I have tried everything, for the last 12 hours, and have not made an inch of progress. I have tried these statements, all yield the same error.
UPDATE scheduling SET start='03:42PM' WHERE activityid=2;
UPDATE scheduling SET start=CONVERT(TIME(6),'03:42PM');
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'03:42PM'));
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'03:42PM'));
INSERT INTO scheduling(start) VALUES (start=CONVERT(TIME(6),'15:42'));
The error is
Syntax Error: unexpected '03:42PM'(single quoted text)"
I do not know how to fix this, the table exists, and i have sucesfully got other info using statements like SELECT activityid=2 FROM xxxxxx.scheudling
I guess I have two questions, either answer would work.
In my PHP document, how would I convert a string I get in from an Android Studio volley to a date. (I get the variable correctly, with $start=$_Post("start"), so that works, but I cant convert it into a time. I looked online, and tried everything that looked like it work work.
Conversion through SQL Code, I already tried CAST and CONVERT, neither works. My start column is type TIME(6).
I recommend testing expressions using a SELECT statement.
Firstly, the MySQL CONVERT function arguments are flipped around backwards.
The syntax is CONVERT(expr,type)
And type is supplied as a keyword, not a string literal. For example:
SELECT CONVERT('235',SIGNED)
To convert to a TIME datatype
SELECT CONVERT( '15:42' ,TIME(6)) // => 15:42:00.000000
The 'PM' part of the string literal will be ignored.
SELECT CONVERT( '03:42PM' ,TIME(6)) // => 03:42:00.000000
We can use the STR_TO_DATE function to return a TIME value from a string that contains the AM/PM indicator
SELECT STR_TO_DATE( '03:42PM' ,'%h:%i%p')
And there's no need to cast that to TIME(6), we can do this:
UPDATE scheduling
SET start = STR_TO_DATE( '03:42PM' ,'%h:%i%p')
WHERE activityid = 2
The STR_TO_DATE function is documented here:
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_str-to-date
The format patterns for STR_TO_DATE are documented here, under DATE_FORMAT:
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format
FOLLOWUP
Demonstration:
setup
USE test;
CREATE TABLE scheduling (activityid INT PRIMARY KEY, start TIME(6));
-- 0 row(s) affected
INSERT INTO scheduling (activityid) VALUES (2);
-- 1 row(s) affected
execute the update statement in the answer above
UPDATE scheduling SET start = STR_TO_DATE( '03:42PM' ,'%h:%i%p') WHERE activityid = 2 ;
-- 1 row(s) affected
results
SELECT * FROM scheduling WHERE activityid = 2;
-- activityid start
-- ---------- ---------------
-- 2 15:42:00.000000
SECOND FOLLOWUP
Use same sql_mode setting reported by OP:
SET ##sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
Test:
SELECT STR_TO_DATE( '03:42PM' ,'%h:%i%p')
returns
(NULL)
But this more complicated expression:
SELECT TIME(STR_TO_DATE(CONCAT(CURRENT_DATE(),' ', '03:42PM' ),'%Y-%m-%d %h:%i%p'))
returns
15:42:00
The more complicated expression is a workaround to avoid behavior imposed by the STRICT_TRANS_TABLES and NO_ZERO_DATE in the sql_mode.
What I'm trying to do
I'm trying to return rows that have a NULL or 0 value in a column where a TIMESTAMP column is before or equal to the current time.
Query
SELECT *
FROM `drafts`
WHERE `leagueid`="vH8j5R0nlsBYhOUm"
AND (`pick_uid`=NULL OR `pick_uid`='0')
AND `deadline` >= "2015-9-28 13:43:00";
NB: I'm using a string value for deadline instead of NOW() because the users have different timezones and so I create a timestamp using the PHP function gmdate to ensure the request is in UTC.
Table Screenshot
What I'm expecting returned from this query
All rows with id<=709.
Probably due to using = with NULL, try this
SELECT *
FROM `drafts`
WHERE `leagueid`="vH8j5R0nlsBYhOUm"
AND (`pick_uid` IS NULL OR `pick_uid`='0')
AND `deadline` >= "2015-9-28 13:43";
It is not possible to test for NULL values with comparison operators, such as =, <, or <>.
We will have to use the IS NULL and IS NOT NULL operators instead.
I have mysql table "announcements" has posts, also has column publish_date which is DateTime
When I build my query like this:
$announcements = Announcement::where('status',1)
->where('publish_date', '<','NOW()')
->orderBy('publish_date', 'DESC')
->paginate(9);
The query log shows:
select * from `announcements`
where `status` = 1 and `publish_date` < NOW()
order by `publish_date` desc
limit 9
offset 0
However, this is my dd($announcements->toArray());
(dont have rep power to post images, http://i.imgur.com/EwTEIzI.png )
If you see the first result has publish_date for August 14, 2014 (Today is 12th)
HOWEVER....
When i RUN IDENTICAL query on the same database in MySQL:
(no rep, no images, sorry: http://i.imgur.com/GQurS6W.png
this is driving me insane
I have tried various combination of single and double quotes in where statements. I have removed pagination, I have removed status, orderby, same result. Even basic insanity-check: cleared cache. No luck
Am I not writing where statement correctly??
THE ONLY HACKJOB solution that works is this:
$now = date('Y-m-d H:i:s');
.....
->where('publish_date', '<', $now)
While this works, this is not a legitimate solution from query standpoint. There are other examples where I need to do MySQL date manipulation and if I cannot use NOW(), for example, it will become difficult to resolve it with PHP alternatives.
I'd rather use native NOW() rather than pass date to query. Thank you guys
Eloquent accepts Carbon dates for this purpose:
$announcements = Announcement::where('status',1)
->where('publish_date', '<',Carbon::now())
->orderBy('publish_date', 'DESC')
->paginate(9);
Otherwise you would probaly use:
$announcements = Announcement::where('status',1)
->where('publish_date', '<',DB::raw('NOW()'))
->orderBy('publish_date', 'DESC')
->paginate(9);
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'))
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.