Returning the oldest timestamp of a query - php

I am trying to get the time of the oldest timestamp in the MySQL table "comment" where the following conditions are met:
Loginid of timestamp is equal to $uid.
Timestamps were made within the last hour.
I have tried the code below and it echoes nothing for $minutes.
How can I get $minutes to echo the oldest timestamp that meets the two conditions above?
EDIT: datecommented is a timestamp.
EDIT 2: $minutes echoes out as a blank space. Could this be a PHP formatting issue?
$result = mysql_query('SELECT * FROM comment WHERE datecommented >= NOW() - INTERVAL 1 HOUR AND loginid = "$uid" ORDER BY datecommented ASC LIMIT 1');
$row = mysql_fetch_array($result);
$minutes = $row['datecommented'];
echo '<div>Test '.$uid.' test '.$minutes.' test.</div>';

please add error checking to your sql query, i suspect your sql is failing
or die(mysql_error());
like this
$result = mysql_query('SELECT * FROM comment WHERE datecommented >= NOW() - INTERVAL 1 HOUR AND loginid = "$uid" ORDER BY datecommented ASC LIMIT 1') or die(mysql_error());
at a guess i would expect the " double quotes around "$uid" should be single quotes,
which means you need to change the single quotes around the whole statement to double quotes
like this
$result = mysql_query("SELECT * FROM comment WHERE datecommented >= NOW() - INTERVAL 1 HOUR AND loginid = '$uid' ORDER BY datecommented ASC LIMIT 1") or die(mysql_error());

You should first try your query on MySQL‘s command line or a tool such as PHPMyAdmin, then you will know if the data being returned is how you expect it.
I also suggest to use a SELECT ... UNIX_TIMESTAMP(thefieldyouwantatimestampfrom) ... WHERE ... in case the column is not storing or returning timestamps as numbers.

Well, if the "datecommented" is in unixtimestamp, then of course it doesn't return the minutes, but seconds. As the unixtimestamp is in seconds.
Does your mysql query even work like that? Or is the actual query problematic too?
Is your $row outputting anything? Try print_r($row);.
However simply put, my answer would be, that you are not converting your raw unxitimestamp into minutes.
You can get your seconds to minutes like this: echo ($row['datecommented'] * 60);
And you can get the minute value of your unixtimestamp like this: echo date("i", $row['datecommented']);

Related

how to delete the expired data from database (depends on a period column)

I want to delete the data that expired.
I have two columns:
created_time : That contain a value indicate to time() function (ex: 1395836716).
period :That contain the period of the remain the row in database (ex: 3 or 7 or 15 or 30 per day).
I want to create a query to check on all rows in the table to know the rows that expired.
The problem is I don't know how to do that, but I tried.
$twentyFour = 60 * 60 * 24;
mysql_query("DELETE FROM content WHERE created_time + (period * $twentyFour ) > '" . time() . "' ");
But unfortunately, did not work as I expected.
Edit:
This is a result of row
Edit 2
I did it, by using php conditions:
$twentyFour = 60 * 60 * 24;
$query = mysql_query("SELECT * FROM content");
while ($data = mysql_fetch_assoc($query)) {
if ($data['created_time'] + ($data['period'] * $twentyFour) < time()) {
mysql_query("DELETE FROM content WHERE id = $data[id]");
}
}
The previous code works fine as was I want.
the problem is the previous code will occurs more server load.
I want a query to doing as the previous code does without using conditions.
DELETE FROM content
WHERE created_time < DATE_ADD(NOW(), INTERVAL `period` DAY)
May I suggest you edit your data structure and include a new column delete_time?
This delete_time should contain the UNIX timestamp of when your column should be deleted calculated from your given period.
Assuming your POST data of the period is numerical value indicating the number of days to save the data for, delete_time should be calculated by
$delete_time = time() + $_POST['period']*24*60*60;
This way, your pruning/deleting query can just be a one-liner:
mysql_query("DELETE FROM content WHERE delete_time < ".time());
That query deletes all rows whose delete_time has passed the current time().
See edit2: of the question
Given that times are held as unix timestamps this is what is required:
DELETE FROM content
WHERE (created_time + period * 60 * 60 * 24) <= NOW()
here is the: SQLFiddle
I had forgotten how much fun playing with dates and times in SQL wasn't ;-/
----------------------------------------
If using 'real' DateTime columns then this is the way to go:
Use:
DELETE FROM content
WHERE created_time < DATE_SUB(NOW(), INTERVAL `period` DAY)
or:
DELETE from content
WHERE NOW() > DATE_ADD(`created_time`, INTERVAL `period` DAY)
Dates and date differences are always difficult to get right. The issue is that you need to pick a reference point:
1) NOW() against created_at + interval,
2) NOW() against `expiry_date
3) created_at + interval against NOW()
4) expiry_date against NOW().
that while you try and work it out, you tend to switch the reference point and it is very non-intuitive.
I have created an SQL Fiddle that demonstrates all the calculations. The 'created_at' date is always midnight to 'simplify' the checking. You can change the variable called 'is_now' and see the result of all the date differences and the boolean results. It is 'interesting', maybe.
TL;DR
SQLFiddle gives the correct answer.

PHP Average of daily averages pulled from mysql

I'm calculating daily averages of $spent in a table using mysql. In php, I'd like to average all those daily averages into 1 average daily average. Eventually, I'd like to do this for multiple tables and graph the final averages in highcharts. Right now, I can't get php to average the results of my query. I am connecting to my database, but just not showing it in the code. See code below:
<?php
function array_average($arr){
$sum = array_sum($arr);
$num = sizeof($arr);
echo $sum/$num;
}
$sth = mysql_query("SELECT round((sum(d_power),2) as $perton FROM pheom.pheom_gb WHERE timestamp between subdate(curdate(), interval 3 month) and curdate() GROUP BY Day(timestamp) ORDER BY Timestamp");
$rows = array();
while($r = mysql_fetch_array($sth)) {
$rows['data'][] = $r['$perton'];
}
echo array_average($rows);
mysql_close($con);
?>
Why not do the calculation in SQL?
select avg($perton) as $perton
from (SELECT round(sum(d_power), 2) as $perton
FROM pheom.pheom_gb
WHERE timestamp between subdate(curdate(), interval 3 month) and curdate()
GROUP BY Day(timestamp)
) t;
Where is $perton coming from? Your query is in double quotes, meaning the variable is being expanded, but your array access is in single quotes so it is not.
If $perton is not defined, then I believe your query will be evaluated as:
SELECT round((sum(d_power),2) as FROM pheom.pheom_gb WHERE timestamp between subdate(curdate(), interval 3 month) and curdate() GROUP BY Day(timestamp) ORDER BY Timestamp
Which is a syntax error.
Additionally, I don't think array_sum works with multidimensional arrays. I would try:
echo array_average( $rows['data'] );
This has nothing to do with PHP or any other scripting language for that matter. This is exactly the kind of thing you should always try to solve within your DB query - you'll get cleaner solutions and much better performance than passing all data to your script just to make a calculation you could've gotten with a single query in the first place. The answer given by Gordon Linoff is the right one.

MySQL current_timestamp - timestamp throws wrong results

Hello in a PHP Script i have the following MySQL Query
$query_players = "SELECT (current_timestamp -`Online_since`) AS `Since` FROM `streams` WHERE `Team` = $temp AND `Online` = 1 ORDER BY `Viewers` DESC";
then i have:
$since = round($obj_players->Since /3600);
As you probably can imagine $since should contain how long the player is already online in hours. Strangely it has wrong results. Its like the time goes faster in MySQL :P
For example after about 15 minutes it already shows "Online since 1 hour" another approximately 30 mins later it already shows 2 hours and so on.
Anyone know what could be wrong? Maybe current_timestamps is the problem?
current_timestamp is not really measured in seconds. So dividing the difference by 3600 doesn't yield hours, but some arbitrary value.
The difference after 18 minutes is 1800 and round(1800/3600) = round(0.5) gives of course 1.
Depending on your real column type use either timediff() or timestampdiff() for your calculation.
Try using TIMESTAMPDIFF:
$query_players = "SELECT TIMESTAMPDIFF(HOUR, NOW(), `Online_since`) AS `Since`
FROM `streams`
WHERE `Team` = $temp
AND `Online` = 1
ORDER BY `Viewers` DESC";

MySQL & PHP: summing up data from a table

Okay guys, this probably has an easy answer but has been stumping me for a few hours now.
I am using PHP/HTML to generate a table from a MySQL Table. In the MySQL table (TimeRecords) I have a StartTime and EndTime column. In my SELECT statement I am subtracting the EndTime from the StartTime and aliasing that as TotalHours. Here is my query thus far:
$query = "SELECT *,((EndTime - StartTime)/3600) AS TotalPeriodHours
FROM TimeRecords
WHERE Date
BETWEEN '{$CurrentYear}-{$CurrentMonth}-1'
AND '{$CurrentYear}-{$CurrentMonth}-31'
ORDER BY Date
";
I then loop that through an HTML table. So far so good. What I would like to do is to add up all of the TotalHours and put that into a separate DIV. Any ideas on 1) how to write the select statement and 2) where to call that code from the PHP/HTML?
Thanks in advance!
Try this
$query= "
SELECT ((EndTime - StartTime)/3600) AS Hours, otherFields, ...
FROM TimeRecords
WHERE
Date BETWEEN '{$CurrentYear} - {$CurrentMonth} - 1'
AND '{$CurrentYear}-{$CurrentMonth} - 31' ";
$records =mysql_query($query);
$sum= 0;
while($row=mysql_fetch_array($records))
{
echo"$row['otherFields']";
echo"$row['Hours']";
$sum+=$row['Hours'];
}
echo" Total Hours : $sum ";
Just use a single query with a Sum(). You could also manually calculate it if you're already displaying all rows. (If paginating or using LIMIT, you'll need a separate query like below.)
$query = "
SELECT Sum(((EndTime - StartTime)/3600)) AS SumTotalPeriodHours
FROM TimeRecords
WHERE
Date BETWEEN '{$CurrentYear} - {$CurrentMonth} - 1'
AND '{$CurrentYear}-{$CurrentMonth} - 31'
";
You can do this in the same query if you have a unique id using GROUP BY WITH ROLLUP
$query = "
SELECT unique_id,SUM((EndTime - StartTime)/3600) AS TotalPeriodHours
FROM TimeRecords
WHERE Date BETWEEN '{$CurrentYear}-{$CurrentMonth}-1'
AND '{$CurrentYear}-{$CurrentMonth}-31'
GROUP BY unique_id WITH ROLLUP
ORDER BY Date
";
In this instance the last result from your query with contain NULL and the overall total. If you don't have a unique ID you will need to do it in PHP as per Naveen's answer.
A few comments on your code:
Using SELECT * is not considered good practice. SELECT the columns you need.
Not all months have a day 31 so this may produce unexpected results. If you're using PHP5.3+, you can use
$date = new DateTime();
$endDate = $date->format( 'Y-m-t' );
The "t" flag here gets the last day of that month. See PHP docs for more on DateTime.

SQL Items within the Last Day

In my code, I am trying to find items in an activities table that are within the last day. This query is not returning any results, are there any problems with it? Is there a better query?
$curday = time() - (24*3600);
$query = "SELECT * FROM activities WHERE userid = '$userid' AND 'timestamp' > '$curday'";
There are two choices here, you can get and format the date through PHP or use SQL language to do it. I prefer to do it within the SQL, it also allows me to use the same query in a MySQL client.
This question is essentially the same thing: MySQL SELECT last few days?
This would be the new query:
$query = "SELECT * FROM activities WHERE userid = '$userid' AND 'timestamp' > DATE_ADD(CURDATE(), INTERVAL -1 DAY)";
you can try with unix function 'mktime' to get value of yesterday ..
as
$curday = mktime(0,0,0,date("m"),date("d")-1,date("Y"));
for reference
if your database will mysql only then you can extract yesterday in sql itself..
SELECT * FROM activities
WHERE userid = '$userid'
AND timestamp > DATE_SUB(CONCAT(CURDATE(), ' 00:00:00'), INTERVAL 1 DAY)
one more thing if timestamp is your column name don't put this column inside single quote ..
What you can use is DATE_SUB. This can be used as follows
SELECT * FROM activities
WHERE userid = '$userid'
AND timestamp > date_sub(current_date, interval 1 day)
This way you don't need to work with current date in PHP
in Informix it would be (TODAY - 1) if the column is type DATE

Categories