PHP & SQL - compare unix timestamp with MySQL CURDATE() - php

i'm trying to do the following thing:
In my Database, I have rows with time in each one (using time() function).
For example: 1380300397.
Now, I'd like to build a query that gets the rows from the current day.
I've tried this query with no success:
SELECT `id`,DATE_FORMAT(`time`, '%Y-%m-%d') FROM `facts`
WHERE `app` = 1 AND DATE(`time`) = CURDATE()
What am I doing wrong?
Thanks!

AND DATE(FROM_UNIXTIME(time)) = CURDATE()

Well you can try use NOW() instead of CURDATE

In my opinion this is the best way to do it. I know it seems to be an overhead at the first glance, but this way you are not applying any function to your column, therefore your query can use index, if you have one on your time column.
SELECT
`id`, DATE_FORMAT(`time`, '%Y-%m-%d')
FROM
`facts`
WHERE
`app` = 1
AND `time` >= UNIX_TIMESTAMP(CONCAT(CURDATE(), ' 00:00:00'))
AND `time` < UNIX_TIMESTAMP(CONCAT(DATE_ADD(CURDATE(), INTERVAL 1 DAY),
' 00:00:00'))

Related

Sql Query to find data only from last hour

I Have An table As Follow
I need Data Only From Last Hour. Following query i tried using Reference.
SELECT * FROM `user_otp`
WHERE `date` = '$todate'
AND datetime > DATEADD(HOUR, -1, GETDATE())
I Dont Know This But I tried Using This Refferance
But It Not Work For Me .
So Any Help Would be useful.
DATEADD and GETDATE() exist in SQL Server.
In MySQL, your conditions should be:
WHERE `datetime` > DATE_ADD(NOW(), INTERVAL -1 HOUR)
While date = '$todate' condition is redundant and should be removed.
Here's a documentation in MySQL DateTime.
Use DATE_SUB and NOW() functions in query
SELECT count(*) as lasthour_count
FROM user_otp
WHERE datetime >= DATE_SUB(NOW(),INTERVAL 1 HOUR);
Hi you can use DATE_SUB function for fetch last one hour data. I edited your code below -
SELECT * FROM `user_otp`
WHERE `date` = '$todate'
AND datetime >= DATE_SUB(NOW(),INTERVAL 1 HOUR);
datetime>=DATE_ADD(NOW(), INTERVAL -1 HOUR);
datetime>= DATE_sub(NOW(), INTERVAL 1 HOUR);
These are the two options you can use

Get one day old record from database

How can i get one day old record from database from server . i have use datetime to insert record. below is how record is look like.
2013-01-15 23:44:02
i have use strtotime('-1 day') but it returns local system time.i want to get one day old record and do some stuff in condition..
Thanx in advance..
where date(date_column) = DATE_sub(NOW(), INTERVAL 1 DAY);
use DATE_ADD
SELECT *
FROM tablename
WHERE DATE(dateCol) = DATE_ADD(CURDATE(),INTERVAL -1 DAY)
DATE_ADD()
SELECT * from table WHERE datefield < DATE_SUB(NOW(), INTERVAL 1 DAY)
You will be archiving this with sql query.
SELECT * FROM tablename WHERE DATE(datefield)=DATE_ADD(CURDATE(),INTERVAL 1 DAY)
CURDATE() will return the current Mysql Server time.
You can use this function DATE_SUB(date,INTERVAL expr type)
http://www.w3schools.com/sql/func_date_sub.asp
Example provided in W3schools
Assume we have the following "Orders" table:
Columns: OrderId, ProductName, OrderDate
Values: 1, Jarlsberg Cheese, 2008-11-11 13:23:44.657
Now we want to subtract 5 days from the "OrderDate" date.
We use the following SELECT statement:
SELECT OrderId,DATE_SUB(OrderDate,INTERVAL 5 DAY) AS SubtractDate
FROM Orders
$yesterday = strtotime('Y-m-d h:i:s','yesterday');
SELECT * FROM tablename WHERE datefield = '$yesterday'

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.

unix timestamps and php

I have a list of unix timestamps in a database, and I wanting to select the ones that are from today.
i.e If today is Tueday, I want to get all the timestamps that were made today? Is it possible? Is there such a things as strtotime("Today")?
Any help would be great
you can use mktime() to generate the timestamp for the start of the day and then find the database entries with a timestamp greater than that.
$start = strtotime(date('Y-m-d 00:00:00')); // Current date, at midnight
$end = strtotime(date('Y-m-d 23:59:59')); // Current date, at 11:59:59 PM
then, you can just select where the timestamp is between the above 2 timestamps:
"SELECT FROM `foo` WHERE `timestamp` BETWEEN '{$start}' and '{$end}'"
You can convert the unix timestamps to sql dates in the SQL using FROM_UNIXTIME(), then compare those to NOW()
SELECT * FROM `tablename` WHERE DATE(FROM_UNIXTIME(`dateFld`)) = DATE(NOW());
Check if DAY(NOW()) and MONTH(NOW()) and YEAR(NOW()) is equal to appropriate value of DAY(timestamp) and MONTH(timestamp) and YEAR(timestamp).
select timestamp from table where DAY(NOW()) = DAY(timestamp) AND MONTH(NOW()) = MONTH(timestamp) AND YEAR(NOW()) = YEAR(timestamp)
If you're using mysql:
SELECT * FROM table WHERE DATE(NOW()) = DATE(FROM_UNIXTIME(timestampcol))
FROM_UNIXTIME(somefield) can be compared to CURDATE() assuming you're using MySQL
SELECT * FROM mytable WHERE FROM_UNIXTIME(datefield,'%Y-%m-%d') = CURDATE();
ETA:
Okay, I was assailed by doubt when this answer was marked down. So I went and did a couple of tests. Given MySQL it definitely works. So why the downmod?
Consider this test which outputs 2 identical fields for every row in a table:
SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(CURDATE()),'%Y-%m-%d') a , CURDATE() b
FROM tablewithsomerows
WHERE FROM_UNIXTIME(UNIX_TIMESTAMP(CURDATE()),'%Y-%m-%d') = CURDATE();

How to minimize the load in queries that need grouping with different invervals?

I'm looking for a best practice advice how to speed up queries and at the same time to minimize the overhead needed to invoke date/mktime functions. To trivialize the problem I'm dealing with the following table layout:
CREATE TABLE my_table(
id INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT,
important_data INTEGER,
date INTEGER);
The user can choose to show 1) all entries between two dates:
SELECT * FROM my_table
WHERE date >= ? AND date <= ?
ORDER BY date DESC;
Output:
10-21-2009 12:12:12, 10002
10-21-2009 14:12:12, 15002
10-22-2009 14:05:01, 20030
10-23-2009 15:23:35, 300
....
I don't think there is much to improve in this case.
2) Summarize/group the output by day, week, month, year:
SELECT COUNT(*) AS count, SUM(important_data) AS important_data
FROM my_table
WHERE date >= ? AND date <= ?
ORDER BY date DESC;
Example output by month:
10-2009, 100002
11-2009, 200030
12-2009, 3000
01-2010, 0 /* <- very important to show empty dates, with no entries in the table! */
....
To accomplish option 2) I'm currently running a very costly for-loop with mktime/date like the following:
for(...){ /* example for group by day */
$span_from = (int)mktime(0, 0, 0, date("m", $time_min), date("d", $time_min)+$i, date("Y", $time_min));
$span_to = (int)mktime(0, 0, 0, date("m", $time_min), date("d", $time_min)+$i+1, date("Y", $time_min));
$query = "..";
$output = date("m-d-y", ..);
}
What are my ideas so far? Add additional/ redundant columns (INTEGER) for day (20091212), month (200912), week (200942) and year (2009). This way I can get rid of all the unnecessary queries in the for loop. However I'm still facing the problem to very fastly calculate all dates that doesn't have any equivalent in database. One way to simply move the problem could be to let MySQL do the job and simply use one big query (calculate all the dates/use MySQL date functions) with a left join (the data). Would it be wise to let MySQL take the extra load? Anyway I'm reluctant to use all these mktime/date in the for loop. Since I have complete control over the table layout and code even suggestions with major changes are welcome!
Update
Thanks to Greg I came up with the following SQL query. However it still bugs me to use 50 lines of sql statements - build up with php - that maybe could be done faster and more elegantly otherwise:
SELECT * FROM (
SELECT DATE_ADD('2009-01-30', INTERVAL 0 DAY) AS day UNION ALL
SELECT DATE_ADD('2009-01-30', INTERVAL 1 DAY) AS day UNION ALL
SELECT DATE_ADD('2009-01-30', INTERVAL 2 DAY) AS day UNION ALL
SELECT DATE_ADD('2009-01-30', INTERVAL 3 DAY) AS day UNION ALL
......
SELECT DATE_ADD('2009-01-30', INTERVAL 50 DAY) AS day ) AS dates
LEFT JOIN (
SELECT DATE_FORMAT(date, '%Y-%m-%d') AS date, SUM(data) AS data
FROM test
GROUP BY date
) AS results
ON DATE_FORMAT(dates.day, '%Y-%m-%d') = results.date;
You definitely shouldn't be doing a query inside a loop.
You can group like this:
SELECT COUNT(*) AS count, SUM(important_data) AS important_data, DATE_FORMAT('%Y-%m', date) AS month
FROM my_table
WHERE date BETWEEN ? AND ? -- This should be the min and max of the whole range
GROUP BY DATE_FORMAT('%Y-%m', date)
ORDER BY date DESC;
Then pull these into an array keyed by date and loop over your data range as you are doing (that loop should be pretty light on CPU).
Another idea is not to use string inside the query. Transform the string parameter to datetime, on mysql.
STR_TO_DATE(str,format)
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html

Categories