Select MySQL rows from within 10 minutes - mysql

I'm storing data like this:
Time - Date
13:20:20 - 2015-03-13
I want to select MySQL entries from within 10 minutes. So if I execute it 13:00 it would be 12:50-13:00.
I've spent ages researching how to use the -interval x minutes, (now) function etc, it just doesn't work... It might be that I'm storing the data badly (varchar type) or timezones issues with server provider
I'm thinking something like SELECT WHERE Time < - 60 seconds AND Date = '2015-03-13'
But it just doesn't work. All help appreciated here.

This is how you do it. Now don't do it. Seriously, have a look at how to do it below but go back and change the way you store dates to be a datetime type column. It makes your life easier and everyone who inherits the application from you (even if it's just a smarter you a year from now) won't hate you for making them do extra work.
create table mytmp
(
mydate varchar(10),
mytime varchar(8)
);
insert into mytmp
values ('2015-01-01', '01:23:45');
insert into mytmp
values ('2015-01-01', '01:24:45');
insert into mytmp
values ('2015-01-01', '01:25:45');
select *
from mytmp
where STR_TO_DATE(CONCAT(mydate, ' ', mytime), "%Y-%m-%d %H:%i:%S") > (now() - INTERVAL 10 minute);
select *
from mytmp
where STR_TO_DATE(CONCAT(mydate, ' ', mytime), "%Y-%m-%d %H:%i:%S") > (now() - INTERVAL 1 year);
drop table my tmp;
The key bit is to get the string date into a datetime format first using STR_TO_DATE. STR_TO_DATE needs a set format so that it can interpret what parts of the string represent what parts of a datetime type (minutes, days, years, etc) so you need to specify a format string. I used the CONCAT function to join your date and time columns into one string to do this. Now the INTERVAL operations will work as you're comparing like or compatible types.
You can find format strings for MySQL here: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format)
Edit: The format string you want is '%H:%i:%s - %Y-%m-%d' by the looks.

Related

Mysql Convert_tz

I'm trying to convert a datetime from Asia/Manila to EST timezone
without declaring the exact interval like
date_sub(), subdate(), date_add(), adddate()
i find it easy to use
SELECT DATE_SUB('2016-04-04 13:00:00', INTERVAL 12 HOUR);
the result will be2016-04-04 01:00:00
But Im trying to create a dynamic script where i don't need to look how many hours is the difference between two timezone
and i find Convert_TZ() to do job
SELECT CONVERT_TZ('2016-04-04 13:00:00', 'Asia/Manila', 'EST');
but the result of this query is 2016-04-04 00:00:00
Maybe this native function is not including the "Daylight saving time(DST)"
Does anyone know how to do the trick?
where i can easily convert the time including the DST
to any timezone without hard coding the interval hour between the two timezone?
Thanks
Okay, my problem is solved, i use two option
First :
I simply use 'US/Eastern' not 'EST' to include the daylight in conversion.
Second:
Because I didn't know the first option earlier i do this to solve my problem at first.
I create a table that compose of the date where it is DST
which i found in some site online..
Then
I create a mysql function where its lookup to the table above
which if the specified date is between that DST Start and DST End it will automatically add 1 hour,
My function is like this,
CREATE FUNCTION usp_Convert(specified_date DATETIME, From_Timezone VARCHAR(20), To_Timezone VARCHAR(20), is_DST INT(1)) RETURNS datetime
DECLARE theDate DATETIME;
SET theDate = CONVERT_TZ(specified_date, From_Timezone, To_Timezone);
IF is_DST = 1 AND To_Timezone= 'EST' THEN
SET theDate = ADDDATE(theDate, INTERVAL 1 HOUR); END IF;
RETURN theDate;
This might not be the best answer but this totally solved my problem
Thanks.

How to compare dates which is stored as String(varchar) in database?

I have a database(table), in which 2 fields are:
fromdate varchar(20)
todate varchar(20)
Dates are stored in this fashion:
YYYY-MM-DD HH:mm:ss
For ex: '2014-10-30 10:10:10' in database.
Now I want to compare two dates and fetch records from database by using query, 2014-09-10 10:10:10(fromdate) to 2014-10-10 10:10:10(todate)
How to fetch all accurate records.. Is there any kind of solution..
Thanks.
Just compare the string without extra overhead.
This format "YYYY-MM-DD HH:mm:ss" shares chronological and literal alphabetical order
SELECT * FROM someTable
WHERE fromdate >= '2014-09-10 10:10:10' AND todate <= '2014-10-10 10:10:10'
Also, I would create an index on those columns.
i have a database(table), in which 2 fields are: fromdate varchar(20)
todate varchar(20)
It is a design flaw. Date should always be a DATE data type and never be string.
dates are stored in this fashion YYYY-MM-DD HH:mm:ss
DATE is never stored in any format. it is for us, human beings to understand.
Oracle stores DATE in total of 7 bytes. Each byte in it stores values for an element of the DATE as follows:
Byte Description
---- -------------------------------------------------
1 Century value but before storing it add 100 to it
2 Year and 100 is added to it before storing
3 Month
4 Day of the month
5 Hours but add 1 before storing it
6 Minutes but add 1 before storing it
7 Seconds but add 1 before storing it
for eg :"2014-10-30 10:10:10" in database.
Now i want to compare two dates and fetch records from database by
using query, 2014-09-10 10:10:10(fromdate) to 2014-10-10
10:10:10(todate)
Just use to_date('2014-10-30 10:10:10', 'YYYY-MM-DD HH24:MI:SS')
NOTE This is for Oracle database. I see you have tagged SQL Server too. I don't understand why did you do that.
Use STR_TO_DATE()
select * from your_table
where str_to_date(fromdate, '%Y-%m-%d %H:%i:%s') >= '2014-09-10 10:10:10'
and str_to_date(todate, '%Y-%m-%d %H:%i:%s') <= '2014-10-10 10:10:10'
First, you can use convert function:
SELECT CONVERT(Datetime, '2014-10-30 18:00:00', 120)
Second, if you can't change the existing columns and their type, it does not mean that you can't add additional column with correct date type that duplicates the meaning of "wrong" column. This would both save your legacy code and help you in new development, as all the operations with convertation in queries are very expensive in terms of performance.

Mysql date interval

I am trying to select rows which are within a certain time period:
$sql = mysql_query(" SELECT * FROM table WHERE ... AND
date BETWEEN ('$date' - Interval 2 YEAR) AND ('$date' + Interval 2 YEAR)
OR date ISNULL");
The format of the dates saved in this column are mm/dd/yyyy
a. how do I select the time interval? currently it is selecting all the rows, not just those within this date range.
b. Am I using the corret syntax to make sure we include all null options as well?
Update.
Following the answers and comments I changed the column type to "Date" (it was varchar), and have also changed the current type of the existing entries to the correct date format.
I now have 2 questions:
a. This is still not working... What else might be the problem?
b. I want to change in PHP where the entry is saved. How ahould I go about this? Is the following correct:
$new_date = mysql_query("STR_TO_DATE($old_date_string,'%m/%d/%Y')");
Solution.
First, I changed the column type to DATE (from VARCHAR).
Second, I moved and converted all the existing entries from their existing column and type (str) to new type (date) and new column.
Third, I added parentheses to the "date" section.
Fourth, I changed ISNULL to IS NULL - addin a space, which changes it from a function to a statement.
Fifth, I am now updating my script so that in the future dates will be saved to the new column in the new type, converting them to the correct fprmat before saving them to the database.
Thankyou #nnicholas and everybody.
If you are really storing your dates as strings I suggest you update your table with something like the following -
-- add a new column of type DATE
ALTER TABLE `table` ADD COLUMN `date_new` DATE AFTER `date`;
-- populate the new column from the old one
UPDATE `table` SET `date_new` = STR_TO_DATE(`date`,'%m/%d/%Y');
-- drop the old column
ALTER TABLE `table` DROP COLUMN `date`;
-- rename the new column
ALTER TABLE `table` CHANGE `date_new` `date` DATE;
After making these changes handling dates will be much easier for you. When inserting the dates that you are receiving you simply use STR_TO_DATE('new_value','%m/%d/%Y') to convert the date during the insert -
mysql_query("INSERT INTO `table` (field1, field2, `date`)
VALUES('value1', 'value2', STR_TO_DATE('$old_date_string','%m/%d/%Y')");
This assumes that $old_date_string has already been sanitised.
With your table structure updated the standard date arithmetic functions will work as intended.
$sql = mysql_query("SELECT *
FROM table
WHERE ...
AND (`date` BETWEEN ('$date' - INTERVAL 2 YEAR) AND ('$date' + INTERVAL 2 YEAR) OR `date` IS NULL)");
$date must be in Y-m-d format.
You can't do date comparisons on it if it's not stored in the database as a date.
You could do something very ugly casting it to a date with STR_TO_DATE() and then comparing but I'd suggest reworking your table structure to store this date as a DATE object.
SELECT * FROM table WHERE ... AND
STR_TO_DATE(date, '%m/%d/%Y') BETWEEN ('$date' - Interval 2 YEAR) AND ('$date' + Interval 2 YEAR)
OR date ISNULL
This assumes that $date is in the correct MySQL DATE format of 2012-03-14 (for 14th March 2012)
You have to CAST/CONVERT your date field that you are getting from MySQL (you really called a date field 'date'? that's a bad idea).
The best answer is to convert your date column to an actual DATE type. You should also not really use the mm/dd/yyyy format as its ambiguous.
You need to enclose the entire date checking part in brackets, like so:
$sql = mysql_query(" SELECT * FROM table WHERE ... AND
(
date BETWEEN ('$date' - Interval 2 YEAR) AND ('$date' + Interval 2 YEAR)
OR date ISNULL
)");
And it should work as expected.
Apart from the missing brackets, your condition seems to take into account NULLs all right (i.e. NULLs would be included in the output regardless of the argument passed).
UPDATE
It seems I was mistaken in presuming that the date column was the date type. #James C has got the point, as well as #nnichols, and their suggestion about changing the column type seems the way to go in your situation.

MySQL Select rows <= now(), using separated time fields

I have a table 't' with date(yyyy-mm-dd), hour(1-12), minute(00-59), ampm(a/p), and timezone(pst/est) fields.
How can I select the rows that are <= now()? (ie. already happened)
Thank you for your suggestions!
edit: this does it without attention to the hour/minute/ap/tz fields:
SELECT * FROM t.date WHERE date <= now()
Here's one way to do it - combine all your seconds, minutes, etc into a date and compare to NOW(), making sure you do the comparison in the same time-zone. (Untested):
SELECT *
FROM t
LEFT JOIN y ON t.constant=y.constant
WHERE CONVERT_TZ(STR_TO_DATE(CONCAT(date,' ',hour,':',minute,' 'ampm),
'%Y-%m-%d %l:%i %p' ),
timezone,"SYSTEM") < NOW();
If your hour is 01 - 12 not 1-12 then use %h instead of %l in the STR_TO_DATE.
The STR_TO_DATE tries to stick your date and time columns together and convert them into a date.
The CONVERT_TZ(...,timezone,"SYSTEM") converts this date from whatever timezone is specified in the timezone column to system time.
This is then compared to NOW(), which is always in system time.
As an aside, perhaps you should make a single column date using MySQL's date datatype, as it's a lot easier to do arithmetic on that!
For reference, here is a summary of very useful mysql date functions where you can read up on those featuring in this answer.
Good luck!
SELECT * FROM t
WHERE `date`<=DATE_SUB(curdate(), INTERVAL 1 DAY)
OR (
`date`<=DATE_ADD(curdate(), INTERVAL 1 DAY)
AND
CONVERT_TZ(CAST(CONCAT(`date`,' ',IF(`hour`=12 AND ampm='a',0,if(ampm='a',`hour`,`hour`+12)),':',`minute`,':00') AS DATETIME),'GMT',`timezone`)<=NOW()
)
Rationale for date<=DATE_[ADD|SUB](curdate(), INTERVAL 1 DAY):
The fancy conversion is quite an expensive operation, so we don't want it to run on the complete table. This is why we pre-select against an UNCHANGED date field (possibly using an index). In no timezone can an event being more than a day in current timezone's past be in the future, and in no timezone can an event more than a day in the curent timezone's future be in the past.

MySQL - return only entries from the past X days

I'm working with a database that has date information stored as a Unix timestamp ( int(11) ) and what I want to do is only return entries from the past X days, the past 90 days for example.
What I've come up with is:
SELECT * FROM mytable WHERE category=1 AND
FROM_UNIXTIME( time ) > DATE_SUB(now(), INTERVAL 91 DAY)
Where 'time' is the int(11) in the db. This seems to be working fine, but just wondering what others think of this.
SELECT * FROM mytable WHERE category=1 AND
time > (UNIX_TIMESTAMP() - ((60*60*24)*90))
or simply
SELECT * FROM mytable WHERE category=1 AND
time > (UNIX_TIMESTAMP() - (86400*90))
this is just comparing a number (seconds in this case)
This query is bound to cause you headaches down the way as MySQL needs to do the conversion of dates for every row making use of indexes impossible. Unix timestamps are numbers, so instead of converting a timestamp to another date format, convert your lookup dates to unix timestamps.
What is the reason for storing the timestamp as an int ? I would use the mysql DATETIME data type because you can use the many Date Time functions mysql has.
If you do not have control over the data type of this field I would convert your date to the unix timestamp int before you do your query and compare it that way.
Just thinking aloud... wouldn't doing it the other way around cause less work for the DB?
time > UNIX_TIMESTAMP( DATE_SUB(NOW(), INTERVAL 91 DAY) )