I am working on a project to graph frequency over a time period. The server currently stores all the data I need apart from the count as this will change over time. I am pulling all of the data that I need using the following code:
<?php
$con = mysql_connect("127.0.0.1",xxx,xxx);
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("tweets", $con);
$results = array();
$result = mysql_query("SELECT company, time FROM data WHERE company = 'AAPL'");
while($row = mysql_fetch_array($result))
{
$results[] = $row;
}
$results = json_encode($results);
mysql_close($con);
echo $results;
?>
When returned I have an array that contains all of the company names and times. how would I go about counting the frequency within a time frame, for example the frequency in the past 24 hours and then a separate value for the previous 24 hours?
You just loop through the data, the exact code depends on the format of the time and the format of the result required. You could do something like this :
$summary =array();
foreach($results as $result)
{
$day = substring($result['time'], 0, 10);
if(isset($summary[$day])){
$summary[$day]++;
} else {
$summary[$day] = 1;
}
}
Write the function getDay() according to the format of the time.
If your date/time values are stored as MySQL datetime (and for your sake I hope they are) then the solution is trivial. Select records within a certain time period and group by company, e.g.
SELECT
`company`, COUNT(`company`) AS total
FROM
`data`
WHERE
`time` >= now() - INTERVAL 1 DAY
GROUP BY
company
In this example I use MySQL to compute the 24 hour period, but you could just as easily have PHP compute an exact time/date.
If you want a pure PHP solution, then start by storing your times grouped by companies in a multidimensional array. Convert your times from your DB format to Unix time. In my example I use strtotime(); if your db times are in a funky format then you'll need to do something else to convert them.
$result = mysql_query("SELECT company, time FROM data");
while($row = mysql_fetch_array($result)) {
$results[$row['company']] = strtotime($row['time']);
}
Then simply loop the array and evaluate.
// 24 hours before now
$start = time() - ( 24*60*60);
$lastTwentyFourHours = array();
foreach ( $results as $company => $times ) {
if ( !isset($lastTwentyFourHours[$company]) ) {
$lastTwentyFourHours[$company] = 0;
}
foreach ( $times as $time ) {
if ( $time >= $start ) {
$lastTwentyFourHours[$company]++;
}
}
}
print_r($lastTwentyFourHours);
Related
how do i get the diffence in time from mysql database and current time. I have tried the below.
$time_db ="SELECT `start`FROM `bookings`";
$w = $conn->query($nam);
if ($w->num_rows > 0)
{
while($row = $w->fetch_assoc())
{
$Current_time=time();
$time_from_db=$row['start'];
}
}
if($time_from_db-$Current_time<=time(1:00)
{
//send email
}
Do not fetch whole table to find relevant rows, instead let MySQL to calculate it for you:
$breaking_time= time() - 60*60; // 1 hour ago
$time_db ="SELECT * FROM `bookings` WHERE `start` < ".gmdate("Y-m-d H:i:s", breaking_time);
$w = $conn->query($nam);
if ($w->num_rows > 0) {
while($row = $w->fetch_assoc()) {
//send email
}
}
I have a MySql table where I saved all workers names and the dates workers have to work on. I want to show a list containg all days of the current month and the worker names who have to work on the day that corresponds to them. Example:
February
1
2
3 - John Wick
5
6 - Martha Beck
etc.
This is the code I have in PHP but the loop is not working. I just get a list from 1 to 30 but it is not showing the data from database. If I run the loop without the (while ($n < 31)), I get all the records from database but I want to show the names just beside the day that correspond.
<?php
mysql_select_db($database_nineras, $nineras);
$query_res = sprintf("SELECT res_id, res_dateini, res_datefin, res_name FROM reservas ORDER BY res_dateini DESC");
$reservas = mysql_query($query_res, $nineras) or die(mysql_error());
$rreser = mysql_fetch_assoc($reservas);
$treser = mysql_num_rows($reservas);
$n = 1;
while ($n < 31) {
do {
++$n;
if ($n == date('d', strtotime($rreser['res_dateini']))) {
echo $n . ' - ' . $rreser['res_name'];
}
else {
echo $n;
}
} while ($rreser = mysql_fetch_assoc($reservas));
}
?>
The problem with your code is that the do-while loop is fetching all the rows returned by the query. So when you get to the second iteration of the while loop there's nothing left to fetch.
Rather than fetch the rows from the database each time through the loop, you can fetch them once and put them into an array whose index is the day numbers. Then you can loop through the days and print all the rows for each day.
Use date('j', ...) to get the date without a leading zero. Or change your SQL query to return DAY(res_dateini).
$results = array();
$reservas = mysql_query($query_res, $nineras) or die(mysql_error());
while ($rreser = mysql_fetch_assoc($reservas)) {
$d = date('j', strtotime($rreser['res_dateini'])));
$results[$d][] = $rreser['res_name'];
}
for ($day = 1; $day <= 31; $day++) {
echo "$day - " . (isset($results[$day]) ? implode(", ", $results[$day]) : "") . "<br>\n";
}
DEMO
I'm building an array of the number of calls I have for a particular client from a mysql db on a running list of the last 30 days. The code I have so far works for adding the days that have calls to the array but I need a show a '0' for the days that have no calls (no entries in the db). Here is me code so far:
$query="SELECT COUNT(*) FROM my_db WHERE client_phone='clint_phone#' GROUP BY calldate";
$result = mysql_query($query);
$data = array();
while ($row = mysql_fetch_row($result)) {
$data[] = $row[0];
}
I just need a way to show if today I had 30 calls and yesterday I had 0, I need it to show [30,0]. What I have only would show [30].
EDIT * I have a mysql db will columns client_phone, calldate. Im looking to build a graph using the data in an array. Each point of the graph will represent a day and the number of calls for that client on that day. Im building the above query to populate that array. I'm trying to count backwards thirty days and feed the total calls for each day into the array.
EDIT 2* I've got it almost there. I'm getting a problem in the 'foreach' area. Below is the code with two print_r()'s to dump the array. The first one looks good, but the second one shows some array entries getting over-written that shouldn't be:
$query="SELECT calldate, COUNT(*) FROM my_db WHERE client_phone='phone#' and calldate>='20130101' AND calldate<='20130107' GROUP BY calldate ORDER BY calldate";
$result = mysql_query($query);
$data = array();
while ($row = mysql_fetch_array($result)) {
$data[$row['calldate']] = $row[1];
}
$startDate = '20130101';
$endDate = '20130107';
$dates = array();
for($current = $startDate; $current != $endDate; $current = date('Ymd', strtotime("$current +1 day"))) {
$dates[] = $current;
}
$dates[] = $endDate;
print_r ($data);
echo "<br />";
foreach($dates as $date){
if (in_array($date, $data)) {
// that date was found in your db_date array(therefore had queries)
}else{
$data[$date] = 0; //date was not found in your db_array so we set that date with no queries to zero
}
}
print_r ($data);
I run this in a browser and I get this:
Array ( [20130101] => 1 [20130104] => 6 [20130105] => 2 [20130106] => 1 [20130107] => 3 )
Array ( [20130101] => 0 [20130104] => 0 [20130105] => 0 [20130106] => 0 [20130107] => 0 [20130102] => 0 [20130103] => 0 )
The top output looks good, just missing a zero assigned to dates not in the data[] array. The second array has zero's in the missing dates, but other overwrited that shouldn't have been.
Thanks for any help!
Finding every date that is in that timespan and doing a task for that does not really that standard of a solution. But depending if your host allows cron-tasks; if you were able to use cron tasks to automatically insert a 0 into your database at 11:59pm for that date if no querys were made that day; you could simply extract all dates.
If you do not want to do it with cron tasks I think you can manage it this way...
$startDate = '2009-01-28';
$endDate = '2009-02-04';
$dates = array();
for($current = $startDate; $current != $endDate; $current = date('Y-m-d', strtotime("$current +1 day"))) {
$dates[] = $current;
$dates[] = $endDate;
}
then do this
foreach($dates as $date){
if (array_key_exists($date, $data)) {
// that date was found in your db_date array(therefore had queries)
}else{
$data[$date] = 0; //date was not found in your db_array so we set that date with no queries to zero
}
}
This may need some minor adjustments because I have not tested it; but this should work; if not something very close to it should. Hope this helps.
I hope you guys have time for an old dog (71 years old) learning new tricks. I have about a week of experience with PHP and mysql but I am having some fun learning how it works and I have made some progress. But I have this query/logic/syntax problem and I would like to get some input if you don't laugh too hard at my meanderings.
I have a calendar program that can't put out the reminders the way I want them. I thought I would take a crack at figuring it out for fun but I can't change the contents of the table lest I trash the whole program. I was succcessful in making it do what I wanted which was to send all my reminders for a single day in one email by just taking the "time" table entries and sorting them and filtering them into what I wanted. But a couple of days later, I noticed that any entry that was before 17:00 my time (GMT -7) was fine but any after that time was garbage. So looking closer at the table, I noticed any time that was after 23:59 GMT was in 5 digits and any before was in 6 digits. So I found the problem. I figured all I needed to do was put an IF in the middle and add extra digits accordingly, change it to UNIX epoch time with strtotime and then do date() and only use the hours and minutes. Are you laughing yet? Let me reiterate, I know very little about PHP and mysql, but I am learning and that makes me happy and maybe a little younger.
Here's what I've got. I'll only send the query because hooking up to the db and sending the mail works fine. This first one works... except for the problem mentioned before...
date_default_timezone_set('America/Denver');
$today = date("Ymd");
mysql_select_db($dbname);
$query = sprintf("SELECT cal_name, cal_time, cal_description, cal_date FROM webcal_entry WHERE cal_date = '".$today."'");
$result = mysql_query($query);
$body = '';
$mail = '';
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
$mail = sprintf("Event: %s \nTime: %s \nDesc: %s \n\n", $row[0], date("H:i",((strtotime($row[1])-25200))), $row[2]);
}
mysql_free_result($result);
This is the crazy fix that is really missing something...
date_default_timezone_set('America/Denver');
$today = date("Ymd");
mysql_select_db($dbname);
$query = sprintf("SELECT cal_name, cal_time, cal_description, cal_date FROM webcal_entry WHERE cal_date = '".$today."'");
$result = mysql_query($query);
$body = '';
$mail = '';
$stt = '';
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
$mail = sprintf("Event: %s \nTime: %s \nDesc: %s \n\n", $row[0], ($stt = { if ($row[1] < 100000, + 1234500000) ELSE ($row[1] + 1234000000) }) date("H:i",((strtotime($stt)-25200))), $row[2])
};
I hope one of you wants to take this on and humor an old guy... and stop laughing!
Try the following. I added comments for easier understanding:
/* I assume that the times and dates in your database are stored in UTC,
so set the UTC timezone first. */
date_default_timezone_set('UTC');
/* $today might now contain a value of tomorrow if it's past 17:00 in your timezone.
This is required though, as there could be an event at e.g. 18:00 of your time which would
not be returned otherwise. sprintf is not needed, as you don't format anyting here */
$today = date("Ymd");
$query = "SELECT cal_name, cal_time, cal_description, cal_date FROM webcal_entry WHERE cal_date = " . $today;
mysql_select_db($dbname);
$result = mysql_query($query);
$body = '';
$mail = '';
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
// Store the value of the returned time in a $fixedTime
$fixedTime = $row[1];
/* Simple approach: While the length of the time is less than 6 digits, prepend a leading 0
This will even work for times like 00:00:15 */
while (strlen($fixedTime) < 6)
$fixedTime = '0' . $fixedTime;
// Now store the unix timestamp (still in UTC!)
$unixEpoch = strtotime($fixedTime);
// Set the timezone to your local time ...
date_default_timezone_set('America/Denver');
// ... and $formattedTime receives the formatted time value in your timezone
$formattedTime = date("H:i", $unixEpoch);
// Now create the mail content
$mail .= sprintf("Event: %s \nTime: %s \nDesc: %s \n\n", $row[0], $formattedTime, $row[2]);
}
mysql_free_result($result);
Database columns containing time and date values should be declared as DATE, TIME or DATETIME though.
That would make things alot easier here, as MySQL can handle both timezone conversion and date/time formatting.
I had this problem some years ago and back then I implemented a "different logic" in order to deliver the project but the doubt remains in my mind and hopefully with your help I'll be able to understand it now.
Suppose I have some scheduled events on my database that may or may not spawn over several days:
id event start end
-----------------------------------------------
1 fishing trip 2009-12-15 2009-12-15
2 fishCON 2009-12-18 2009-12-20
3 fishXMAS 2009-12-24 2009-12-25
Now I wish to display the events in a calendar, lets take the month of December:
for ($day = 1; $day <= 31; $day++)
{
if (dayHasEvents('2009-12-' . $day) === true)
{
// display the day number w/ a link
}
else
{
// display the day number
}
}
What query should the dayHasEvents() function do to check if there are (or not) events for the day? I'm guessing SELECT .. WHERE .. BETWEEN makes the most sense here but I've no idea how to implement it. Am I in the right direction?
Thanks in advance!
#James:
Lets say we're on December 19th:
SELECT *
FROM events
WHERE start >= '2009-12-19 00:00:00'
AND end <= '2009-12-19 23:59:59'
Should return the event #2, but returns nothing. =\
You should scratch that approach and grab all events for the given month up front so you only need to perform a single query as opposed to N queries where N is the number of days in the month.
You could then store the returned results in a multidimensional array like so:
// assume event results are in an array of objects in $result
$events = array();
foreach ($result as $r) {
// add event month and day as they key index
$key = (int) date('j', strtotime($r->start));
// store entire returned result in array referenced by key
$events[$key][] = $r;
}
Now you'll have a multidimensional array of events for the given month with the key being the day. You can easily check if any events exist on a given day by doing:
$day = 21;
if (!empty($events[$day])) {
// events found, iterate over all events
foreach ($events[$day] as $event) {
// output event result as an example
var_dump($event);
}
}
You're definitely on the right track. Here is how I would go about doing it:
SELECT *
FROM events
WHERE start <= '2009-12-01 00:00:00'
AND end >= '2009-12-01 23:59:59'
And you obviously just replace those date values with the day you're checking on.
James has the right idea on the SQL statement. You definitely don't want to run multiple MySQL SELECTs from within a for loop. If daysHasEvents runs a SELECT that's 31 separate SQL queries. Ouch! What a performance killer.
Instead, load the days of the month that have events into an array (using one SQL query) and then iterate through the days. Something like this:
$sql= "SELECT start, end FROM events WHERE start >= '2009-12-01' AND end <= '2009-12-31'";
$r= mysql_query($sql);
$dates= array();
while ($row = mysql_fetch_assoc($r)) {
// process the entry into a lookup
$start= date('Y-m-d', strtotime($row['start']));
if (!isset($dates[$start])) $dates[$start]= array();
$dates[$start][]= $row;
$end= date('Y-m-d', strtotime($row['end']));
if ($end != $start) {
if (!isset($dates[$end])) $dates[$end]= array();
$dates[$end][]= $row;
}
}
// Then step through the days of the month and check for entries for each day:
for ($day = 1; $day <= 31; $day++)
{
$d= sprintf('2009-12-%02d', $day);
if (isset($dates[$d])) {
// display the day number w/ a link
} else {
// display the day number
}
}
For your purposes a better SQL statement would be one that grabs the start date and the number of events on each day. This statement will only work properly if the start column is date column with no time component:
$sql= "SELECT start, end, COUNT(*) events_count FROM events WHERE start >= '2009-12-01' AND end <= '2009-12-31' GROUP BY start, end";