How do I get rows for last 24 hours by unixstamp - php

I have this;
$long = "86400";
$query = "SELECT * FROM users WHERE unixdate = UNIX_TIMESTAMP()-$long
ORDER BY unixdate DESC";
But it doesn't work. I would like to show all new users within 24 hours

You can do that query completely in MySQL with
SELECT col1, col2, otherCols
FROM yourTable
WHERE timestamp_col > (NOW() - INTERVAL 24 HOUR)
The expression (NOW() - INTERVAL 24 HOUR) returns the date 24 hours ago. MySql is smart enough to handle comparisons between Time related column types.
If timestamp_col is not a time related type, but something like a varchar or int column you have to use FROM_UNIXTIME on the column or adjust the above query to read
SELECT col1, col2, otherCols
FROM yourTable
WHERE timestamp_col > UNIX_TIMESTAMP( NOW() - INTERVAL 24 HOUR )
See DATE_SUB and DATE_ADD in the MySql Manual.

Use > instead of =. At the moment, you are querying for entries created at a certain second which will hardly ever match.

You're looking for new users within the last 24h, not exactly 24h. So you have to use the > (greater than) operator instead of = (equals).
$long = "86400";
$query = "SELECT * FROM users WHERE unixdate > UNIX_TIMESTAMP()-$long ORDER BY unixdate DESC";
By the way, PHP has a function equivalent to MySQL UNIX_TIMESTAMP() function: time();

You must convert the timestamp file to date for the comparison.
SELECT * FROM table WHERE (from_unixtime(unixdate) >= NOW() - INTERVAL 1 DAY)

Related

timestamp query not retrieving results?

Hi there :) I am doing a query, and it will pull results where the timestamp is more than 30 days old. Here's what I've put so far:
$result = $db->query("SELECT time FROM table1 WHERE open_time < (NOW() - INTERVAL 30 DAYS)");
So as you can see, it will try to find results more than 30 days old, however when I execute the query, it doesn't select any rows, even though the column field "open_time" is more than 30 days old.
Any suggestions I do greatly appreciate :)
Have you tried to cast the date field?
$result = $db->query("SELECT time FROM table1 WHERE CAST(open_time AS DATE) < (NOW() - INTERVAL 30 DAYS)");
EDIT:
Maybe you should use this tricky query:
$result = $db->query("SELECT time FROM table1 WHERE open_time <
UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 30 DAY))"):
Try this Query
$result = $db->query("SELECT time FROM table1 WHERE DATE(`date`) = DATE(NOW() - INTERVAL 30
DAY")
or
try this one also for your reference
timestampadd()
SELECT * FROM table WHERE `date` > timestampadd(day, -30, now());
try this link also

Comparing dates and times in different fields

Now, I've a problem with the following query:
SELECT *
FROM table
WHERE date > CURDATE()
OR date = CURDATE()
AND time > CURTIME()
It's return rows with date > of today but I need also rows with date of today but with time > of the current time.
You need to put the related clauses inside parenthesis:
SELECT *
FROM table
WHERE date > CURDATE()
OR (
date = CURDATE()
AND time > CURTIME()
)
You should use the appropriate date/time functions instead of complicating yourself with complex WHERE clauses:
SELECT * FROM TABLE
WHERE ADDTIME(date, time) > NOW()
More information on the ADDTIME function in this link.

Very specific MySQL query I want to improve

This is my scenario: I have a table that contains events, every event has a field called 'created' with the timestamp in which that event was created. Now I need to sort the events from newest to oldest, but I do not want MySQL to return them all. I need only the latest in a given interval, for example in a range of 24 hours (EDIT: I'd like to have a flexible solution, not only for a 24 hours range, but maybe every few hours). And I only need for the last 10 days. I have achieved that but i'm sure in the most inefficient ways possible, that is, something like that:
$timestamp = time();
for($i = 0; $i < 10; $i++) {
$query = "SELECT * FROM `eventos` WHERE ... AND `created` < '{$timestamp}' ORDER BY `created` DESC LIMIT 1";
$return = $database->query( $query );
if($database->num( $return ) > 0) {
$event = $database->fetch( $return );
$events[] = $event;
$timestamp = $timestamp - 86400;
}
}
I hope I was clear enough. Thanks,
Jesús.
If you have an index with created as the leading column, MySQL may be able to do a reverse scan. If you have a 24 hour period that doesn't have any events, you could be returning a row that is NOT from that period. To make sure you're getting a row in that period, you would really need to include a lower bound on the created column as well, something like this:
SELECT * FROM `eventos`
WHERE ...
AND `created` < FROM_UNIXTIME( {$timestamp} )
AND `created` >= DATE_ADD(FROM_UNIXTIME( {$timestamp} ),INTERVAL -24 HOUR)
ORDER BY `created` DESC
LIMIT 1
I think the big key to performance here is an index with created as the leading column, along with all (or most) of the other columns referenced in the WHERE clause, and making sure that index is used by your query.
If you need a different time interval, down to the second, this approach could be easily generalized.
SELECT * FROM `eventos`
WHERE ...
AND `created` < DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL 0*{$nsecs} SECOND)
AND `created` >= DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -1*{$nsecs} SECOND)
ORDER BY `created` DESC
LIMIT 1
From your code, it looks like the 24-hour periods are bounded at an arbitrary time... if the time function returns e.g. 1341580800 ('2012-07-06 13:20'), then your ten periods would all be from 13:20 on a given day to 13:20 the following day.
(NOTE: be sure that if your parameter is a unix timestamp integer, that this is being interpreted correctly by the database.)
It might be more efficient to pull the ten rows in a single query. If there is a guarantee that 'timestamp' is unique, then it's possible to craft such a query, but the query text will be considerably more complex than what you have now. We could mess with getting MAX(timestamp_) within each period, and then joining that back to get the row... but that's going to be really messy.
If I were going to try to pull all ten rows I would probably try going with a UNION ALL approach, not very pretty, but it least it could be tuned.
SELECT p0.*
FROM ( SELECT * FROM `eventos` WHERE ...
AND `created` < DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL 0*24 HOUR)
AND `created` >= DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -1*24 HOUR)
ORDER BY `created` DESC LIMIT 1
) p0
UNION ALL
SELECT p1.*
FROM ( SELECT * FROM `eventos` WHERE ...
AND `created` < DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -1*24 HOUR)
AND `created` >= DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -2*24 HOUR)
ORDER BY `created` DESC LIMIT 1
) p1
UNION ALL
SELECT p2.*
FROM ( SELECT * FROM `eventos` WHERE ...
AND `created` < DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -2*24 HOUR)
AND `created` >= DATE_ADD(FROM_UNIXTIME({$timestamp}),INTERVAL -3*24 HOUR)
ORDER BY `created` DESC LIMIT 1
) p2
UNION ALL
SELECT p3.*
FROM ...
Again, this could be generalized, to pass in a number of seconds as an argument. Replace HOUR with SECOND, and replace the '24' with a bind parameter that has a number of seconds.
It's rather long winded, but it should run okay.
Another really messy and complicated way to get this back in a single result set would be to use an inline view to get the end timestamp for the ten periods, something like this:
SELECT p.period_end
FROM (SELECT DATE_ADD(t.t_,INTERVAL -1 * i.i_* {$nsecs} SECOND) AS period_end
FROM (SELECT FROM_UNIXTIME( {$timestamp} ) AS t_) t
JOIN (SELECT 0 AS i_
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
) i
) p
And then join that to your table ...
ON `created` < p.period_end
AND `created` >= DATE_ADD(p.period_end,INTERVAL -1 * {$nsecs} SECOND)
And pull back MAX(created) for each period GROUP BY p.period_end, wrap that in an inline view.
And then join that back to your table to get each row.
But that is really, really messy, hard to understand, and not likely to be any faster (or more efficient) than what you are already doing. The most improvement you could make is the time it takes to run 9 of your queries.
Assuming you want the latest (having the greatest created date) event per day for the last 10 days.
so let's get the latest timestamp per day
$today = date('Y-m-d');
$tenDaysAgo = date('Y-m-d', strtotime('-10 day'));
$innerSql = "SELECT date_format(created, '%Y-%m-%d') day, MAX(created) max_created FROM eventos WHERE date_format(created, '%Y-%m-%d') BETWEEN '$today' and '$tenDaysAgo' GROUP BY date_format(created, '%Y-%m-%d')";
Then we can select all the events that match those created dates
$outerSql = "SELECT * FROM eventos INNER JOIN ($innerSql) as A WHERE eventos.created = A.max_created";
I haven't had a chance to test this, but the principles should be sound enough.
If you want to group by some other arbitrary number of hours you would change innerSql:
$fromDate = '2012-07-06' // or if you want a specific time '2012-07-06 12:00:00'
$intervalInHours = 5;
$numberOfIntervals = 10;
$innerSql = "SELECT FLOOR(TIMESTAMPDIFF(HOUR, created, '$fromDate') / $intervalInHours) as grouping, MAX(created) as max_created FROM eventos WHERE created BETWEEN DATE_SUB('$fromDate', INTERVAL ($intervalInHours * $numberOfIntervals) HOUR) AND '$fromDate' GROUP BY FLOOR(TIMESTAMPDIFF(HOUR, created, '$fromDate') / $intervalInHours)";
I'd add another column that is the date(not time) and then use MySQL "group by" to get the most recent for each date.
http://www.tizag.com/mysqlTutorial/mysqlgroupby.php/
This tutorial does just that, but by product type instead of date. This should help!
Do you want all of the events within the 10 days, or just one event per day within the 10 day period?
Either way, consider MySQL's date functions for assistance. It should help you get the date range you want.
Here's one that will get you the first event of the day for the last 10 days.
SELECT *
FROM eventos
WHERE created BETWEEN DATE_SUB(DATE(NOW()), INTERVAL 10 DAY) AND DATE_ADD(DATE(NOW()), INTERVAL 1 DAY)
GROUP BY DATE(created)
ORDER BY MAX(created) DESC
LIMIT 10
Try this:
SELECT *
FROM eventos
WHERE created BETWEEN DATE_SUB(DATE(NOW()), INTERVAL 10 DAY) AND DATE_ADD(DATE(NOW()), INTERVAL 1 DAY)
ORDER BY created DESC
LIMIT 10

Select rows from MySQL table where PHP timestamp is older than X

I have a user table, where users need to be approved, i want to show users who are not approved and is registered more than 7 days ago.
My user_regdate is a timestamp created with php time() function.
This is what i try, it does not works:
mysql_query("select * from users WHERE user_regdate < now() - interval 7 day AND approved='0' order by id;");
Thanks
PHP's timstamps are a simple integer, whereas MySQL's now() returns a datetime value. Most likely this will fix up the query:
SELECT ... WHERE user_regdate < unix_timestamp(now() - interval 7 day)) ...
Basically, without the unix_timstamp() call, you're comparing apples and oranges.
Primitive solution at best, but im not the best at MySQL time calculation
$timestamp = strtotime("-7 days");
mysql_query("SELECT * FROM users WHERE user_regdate < $timestamp AND approved = 0 ORDER BY id");
php's time() function outputs a unix timestamp (the number of seconds since January 1 1970). MySQL's now() function outputs a formatted date (like 2011-6-9 12:45:34)... so I don't think you can compare them like that.
Try using the unix timestamp, minus 7 days, instead of now() in your query:
$7_days_ago = time() - (7 * 24 * 60 * 60);
mysql_query("select * from users WHERE user_regdate <" . $7_days_ago . " AND approved='0' order by id;");
Try this;
select *
from users
WHERE DATE_SUB(user_regdate,INTERVAL 7 DAY)
AND approved='0'
order by id;

SQL Query to show number of stories created in last 24 hours?

I'm trying to create a custom query that will show the number of stories that have been posted in the last 24 hours on a Drupal 6 site.
Stories are stored in the "node" table. each record has a "created" row that records the UNIX timestamp when the story was posted.
Here's the query I'm trying so far:
$sq = 'SELECT COUNT(*) cnt '
. 'FROM {node} c WHERE created >= dateadd(hour,-24,getdate())';
This doesn't appear to be working though. What am I doing wrong?
EDIT: Here's the overall code I'm trying to use right now:
$sq = 'SELECT COUNT(*) AS cnt FROM {NODE} n WHERE FROM_UNIXTIME(n.created) >= DATE_SUB(NOW(), INTERVAL 1 DAY)';
$q = db_query($sq);
while ($o = db_fetch_object($q)) {
print_r($o);
}
That print_r isn't returning anything. Where's my error?
For MySQL, use:
SELECT COUNT(*) AS cnt
FROM NODE n
WHERE FROM_UNIXTIME(n.created) >= DATE_SUB(NOW(), INTERVAL 1 DAY)
Mind that NOW() includes the time when the statement is run. If you want to count records, starting from midnight of the previous day, use:
SELECT COUNT(*) AS cnt
FROM NODE n
WHERE FROM_UNIXTIME(n.created) >= DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY)
Reference:
FROM_UNIXTIME
DATE_SUB
Since you are doing this in PHP, you can just use $_SERVER['REQUEST_TIME']. My guess is that it will be faster than doing date manipulations with SQL:
$count = db_result(db_query("SELECT COUNT(nid) FROM {node}
WHERE created >= %d;", $_SERVER['REQUEST_TIME'] - 86400));
Alternative you could use time to get the current timestamp, but that will be a tiny bit slower than using the $_SERVER['REQUEST_TIME'] variable.

Categories