How to find if entire week(s) past from creation on mySQL? - mysql

I am looking for a solution to find with mySQL every result that was created since a(or many) entire week(s) (7 days).
I tried this but it seems sometimes the result is false because is there more than one result per week.
SELECT *
FROM `datatable`
WHERE MOD(TIMESTAMPDIFF(DAY,UNIX_TIMESTAMP(created),NOW()),7)=0;
created is a timestamp.
Thanks for any response!

Try this:
SELECT
*
FROM
`datatable`
WHERE 1
AND `created` >= DATE_FORMAT(NOW() - INTERVAL 7 DAY,'%Y-%m-%d 00:00:00')
AND `created` <= DATE_FORMAT(NOW() - INTERVAL 7 DAY,'%Y-%m-%d 23:59:59')

UNIX_TIMESTAMP(), UNIX_TIMESTAMP(date)
If called with no argument, returns a Unix timestamp (seconds since
'1970-01-01 00:00:00' UTC) as an unsigned integer. If UNIX_TIMESTAMP()
is called with a date argument, it returns the value of the argument as
seconds since '1970-01-01 00:00:00' UTC, date may be a DATE string, a
DATETIME string, a TIMESTAMP, or a number in the format YYMMDD or
YYYYMMDD. The server interprets date as a value in the current time
zone and converts it to an internal value in UTC. Clients can set their
time zone as described in
http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html.
So, do not use UNIX_TIMESTAMP() function, but simple DATE().

As far as I can understand the question, you want the records that are are newer than a certainDate, AND not older than 7 days, or 14 days,..., 140 days (whichever of them is closest to the certainDate) from current date.
IF I understand you correctly, following might work for you with certainDate = '2013-04-01 00:00:00'
SELECT *
FROM `datatable`
WHERE `created` >= ADDDATE(
'2013-04-01 00:00:00',
INTERVAL MOD(ABS(TIMESTAMPDIFF(DAY, NOW(), '2013-04-01 00:00:00')),7) DAY
)
This query will fetch all results having created in last 14 days.

Related

Create datetime with specific time mySql

I'm looking to create a date time field in a MySQL script that has a specific date and time.
I've tried using
CONCAT(DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 9 DAY) ,'%Y%m%d'), ' 13:00:00')
but it doesn't insert correctly.
How can I achieve this so that it will insert a date time with the time as above?
It inserts the record as 0000-00-00 00:00:00 with the above
mysql accepts datetime values in yyyy-mm-dd hh:mm:ss format. In your formula you do not separate the year, month, day values, hance the result is not in the date format mysql expects the dates in. Change it to:
CONCAT(DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 9 DAY) ,'%Y-%m-%d'), ' 13:00:00')
But I do not really understand why you need to do the formatting, just use CURDATE() function instead of the NOW():
CONCAT(DATE_SUB(CURDATE(), INTERVAL 9 DAY), ' 13:00:00')

Select all MySQL records in the last day that are between a time range of 7am and midnight

I have this query
SELECT * FROM `timeclock_timecard`
WHERE `clock_in_datetime` > DATE_SUB(CURDATE(), INTERVAL 1 DAY)
which can get record in the last day but I need to limit to records created after 7AM
Any help please?
SELECT * FROM `timeclock_timecard`
WHERE `clock_in_datetime` > DATE_SUB(CURDATE(), INTERVAL 1 DAY)
and hour(`clock_in_datetime`) > 7;
Added one more filter condition to check for the hour.
Your query was almost correct, because CURDATE() only gives the date you can just subtract 17 hours to get the correct result. fiddle.
SELECT * FROM `timeclock_timecard`
WHERE `clock_in_datetime` >= DATE_SUB(CURDATE(), INTERVAL 17 HOUR)
To get the entries of the current day, we can add 7 hours (CURDATE() has time 0:00).
SELECT * FROM `timeclock_timecard`
WHERE `clock_in_datetime` >= DATE_ADD(CURDATE(), INTERVAL 7 HOUR)
To get only rows from yesterday, with a time value of 7AM or later, we can add 7 hours to the expression.
If we only up until midnight of today (just rows from yesterday), we can add another condition, the datetime is less than midnight today.
For example:
SELECT t.*
FROM `timeclock_timecard` t
WHERE t.`clock_in_datetime` >= DATE(NOW()) + INTERVAL -1 DAY + INTERVAL 7 HOUR
AND t.`clock_in_datetime` < DATE(NOW())
If you want to exclude the exact 7:00:00 AM value, change the >= to just >.
FOLLOWUP
Q: What I actually want is between about 5-6am TODAY and mindnight TODAY so anytime during today that I run the report for today I will get only timeclock data from users who clocked in/out today only and not include yesterdays data.
A: The predicates are going to be of the form
WHERE t.`clock_in_datetime` >= expr1
AND t.`clock_in_datetime` < expr2
You just need to find the expressions expr1 and expr2 that return the appropriate datetime values.
Just use a simple SELECT statement to test:
SELECT DATE(NOW()) + INTERVAL 5 HOUR AS `start`
, DATE(NOW()) + INTERVAL 1 DAY AS `end`
Q: I also modified my select to take in account my datetime is in UTC and my result needs to get todays records using local timezone.
SELECT * , CONVERT_TZ( clock_in_datetime , '+00:00', '-4:00' ) FROM `timeclock_timecard`
A: Personally, I would do the timezone conversion on the exprN values, not the column values. Having predicates on bare columns allows MySQL to make effective use of an index; wrapping the columns in expressions prevents MySQL from using an index.
If the MySQL system clock is UTC, and your datetime values stored in the table are in a different timezone, yes, use the MySQL CONVERT_TZ function.
Again, using a simple SELECT statement to develop and test the expressions:
SELECT CONVERT_TZ( DATE(NOW()) + INTERVAL 5 HOUR, '+0:00', to_tz) AS `start`
, CONVERT_TZ( DATE(NOW()) + INTERVAL 1 DAY , '+0:00', to_tz) AS `end`
Where to_tz is the timezone of the values in the table.
Once you get expressions start and end returning the values you need, then use those expressions in the predicates of the query of the timecard table.

MySQL substract two datetimes and returns in nanoseconds

I have 2 datetime columns in a MySQL table.
I want to subtract it and return the results and a nanoseconds precision
This is my code so far.
select end,start,end-start from job where id=1;
I have the results like this
'2014-04-02 12:30:00', '2014-04-02 10:30:00', 20000.000000
Just for curiosity how MySQL subtract directly, how 20000.000000 came from.
I am not good handling dates. Which is the best approach?
unix_timestamp: If you want to convert a UNIX TIMESTAMP into seconds since '1970-01-01'
If called with no argument, returns a Unix timestamp (seconds since
'1970-01-01 00:00:00' UTC) as an unsigned integer. If UNIX_TIMESTAMP()
is called with a date argument, it returns the value of the argument
as seconds since '1970-01-01 00:00:00' UTC. date may be a DATE string,
a DATETIME string, a TIMESTAMP, or a number in the format YYMMDD or
YYYYMMDD.
Consider this :
SELECT unix_timestamp(now()) - unix_timestamp('2007-03-19 09:50:00')
You want this:
SELECT unix_timestamp(column1) - unix_timestamp(column2) from tableName
See it in action
SELECT start_time,
end_time,
( Unix_timestamp(start_time) - Unix_timestamp(end_time) ) * 1000000000 AS
NanoSeconds
FROM job
Output:
start_time | end_time | NanoSeconds
April, 02 2014 12:30:00 April, 02 2014 10:30:00 7200000000000
As we can format this datetime column value also with DATE_FORMAT(). TO_SECONDS() is available beginning with MySQL 5.5.0.
MYSQL - datetime to seconds also gives some lightness on another solution of the output you want.

Date Interval Bug

I have a table which has a column called created DATETIME, When adding entries It works fine, but when It gets to Date Interval, It keeps on duplicating new entries. I'm trying to get Today's and Yesterday's entries. Today's works fine, but for Yesterday's, It also puts on Today's contents in query results which Is not what I want.
SELECT * FROM tab WHERE created > DATE_SUB(NOW(), INTERVAL $num DAY) ORDER BY created DESC LIMIT 9;
$num Is 1 for Today's entries, and It's 2 for Yesterday's. So basically an entry which Is created today, Is getting duplicated on Yesterday's query results.
You are getting the results you requested from the database. Namely any record that is greater than today minus however many days you put in.
The reason you get 0 records when you try #KenWhite's suggested of changing your > to = is because your field is DATETIME, so subtracting exactly 24 hours from NOW() yields the same exact time yesterday and you probably don't have a record that was written precisely at this time yesterday. Right?
What you'll have to do is test for records between two dates to get you want. Instead of NOW(), switch to CURDATE(), this way you can be assured you'll get every record for the datetime range you are looking for.
SELECT *
FROM tab
WHERE
created BETWEEN DATE_SUB(CURDATE(), INTERVAL $num DAY) AND DATE_SUB(CURDATE(), INTERVAL $num - 1 DAY)
ORDER BY created DESC LIMIT 9;
You can check out a SQLFiddle of this here: http://sqlfiddle.com/#!2/19d9b/12
With datetime/timestamp values, similar to floats, always use ranges with closed beginnings and open endings. So use '>=' and '<'.
For example to use the data of a single day:
SELECT ... FROM tab
WHERE created >= CURDATE() - INTERVAL #num:=? DAY
AND created < CURDATE() - INTERVAL #num DAY + INTERVAL 1 DAY
ORDER BY created DESC
LIMIT 9
;
With MySQL, generally prefer the timestamp type over the datetime type, as datetime doesn't carry timezone information.
Alternatives:
created_at timestamp NULL DEFAULT NULL COMMENT 'set by application',
created_at timestamp NOT NULL DEFAULT '1970-01-01 23:00:00' COMMENT 'set by application',
dbms_row_created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'set by DBMS',

Find records with a time field in the last 24 hours

In my SQL query how do i find records in the last 24 hours?
I am using time() function for inserting into db.
I am using time-stamp the time is stored in this format.Eg 1332673046
select somefield from yourtable where timefield >= subtime(current_timestamp(), '1 00:00:00');
You can use BETWEEN
SELECT * FROM users
WHERE created_at BETWEEN '2012-03-31 00:00:00 UTC' AND '2012-03-31 23:59:59 UTC'
I am not certain if you are looking to check within the same calendar day, or as you say within the past 24 hours, so here's what I usually do for both cases:
a) For the same calendar day:
CONVERT(VARCHAR(8), myTable.myDate, 112) = CONVERT(VARCHAR(8), GETDATE(), 112)
b) For the date to be within the past 24 hours (inclusive)
DATEDIFF(hour, myTable.myDate, GETDATE()) <= 24
Simple DATE arithmetic would do,
SELECT *
FROM `table1`
WHERE `time_col` BETWEEN NOW() AND NOW()- INTERVAL 24 HOURS;
Given that you are storing dates as unix timestamps then you need UNIX_TIMESTAMP like this
SELECT
// fields you need
FROM `table`
WHERE
`date_field` BETWEEN UNIX_TIMESTAMP( DATE_SUB(NOW() INTERVAL 24 HOUR) ) AND UNIX_TIMESTAMP()
You might want to consider storing dates in MySQLs DATETIME format as it makes date calculations in MySQL much easier.