How should I make this SQL Query more efficent - php

I am searching up a database to find the past 7 days worth of data, accumulated.
It works perfectly, but I currently have seven editions of the same code - so I want to loop it somehow, however if I do that, how do I loop it correctly and name the variables. Aside from naming the variables (day_X_) I think I should be able to loop it 7 times fairly easily...
// Get the current day
$graph_day_1_date_lower = date('Y-m-d') . " 00:00";
$graph_day_1_date_upper = date('Y-m-d') . " 23:59";
$graph_day_1_name = date('D') . " (Today)";
/* Successes */
$graph_day_1 = mysqli_query($con,
"SELECT COUNT(`id`) AS num FROM `hidden`
WHERE submittedtime >= '$graph_day_1_date_lower'
AND submittedtime < '$graph_day_1_date_upper'
AND u_s_code='C001'")
or die(mysqli_error($con));
$graph_day_1_row = mysqli_fetch_assoc($graph_day_1);
$graph_day_1_count = $graph_day_1_row['num'];
$graph_total_count = $graph_day_1_count;
/* Errors */
$graph_e_day_1 = mysqli_query($con,
"SELECT COUNT(`id`) AS num FROM `hidden`
WHERE submittedtime >= '$graph_day_1_date_lower'
AND submittedtime < '$graph_day_1_date_upper'
AND u_s_code='E001'")
or die(mysqli_error($con));
$graph_e_day_1_row = mysqli_fetch_assoc($graph_e_day_1);
$graph_e_day_1_count = $graph_e_day_1_row['num'];
$graph_e_total_count = $graph_e_day_1_count;
I will then print the two total counts for each day

Here's what you would want to do:
$today = time(); // or use your upper / lower bounds
$daysToShow = 7;
$dayData = array();
for($i = 0; $i < $daysToShow; $i++){
$dateToCheck = $today + ($i * 24 * 60 * 60); // add a day each time $i goes up
$dataArray = mysql_fetch_assoc($yourDataHere); // replace with your mysqli query using $dateToCheck
$dayData[] = $dataArray; // add to array
}
foreach($dayData as $day){
echo $day['name']; // print out your info here
}

Related

Inputting/overwriting information in arrays with PHP

I have a small PHP page which takes data from MySQL and displays it via PHP in a monthly calendar. I'm having trouble arranging the data properly within an array to get the desired output.
First, I will describe what I would like to happen:
students come to classes on regular days of the week
they can also make or cancel reservations
the calendar also displays days when the school is not open
In order to display this data on the calendar, I use MySQL to output data from a variety of sources, and then input that into an array with PHP, which I sort by date and output.
My issue is, I would like to be able to handle more than one row of data per day, but because I am using the date as the key, I am limited on only displaying one result per day. If I use a loop to append the date with a counter in the key, I get overlapping results in situations where someone made a reservation and then cancelled that reservation on the same day.
As for my code...
First, I check to see if the student is registered in a weekly class, then input that class into the array.
$sql = "SELECT StudentDB.studentid, ClassDB.classID, ClassDB.class_level, ClassDB.class_title, ClassDB.time, ClassDB.teacher, StudentDB.first_name, StudentDB.last_name, StudentDB.payment_amount, ClassDB.day
FROM ClassDB
INNER JOIN RegDB ON ClassDB.classID = RegDB.classid
INNER JOIN StudentDB ON StudentDB.studentID = RegDB.studentid
WHERE StudentDB.studentid = '$studentid'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) { // DISPLAY REGULAR CLASS DATA
$dayofclass = $row['day'];
$class_level = $row['class_level'];
$class_title = $row["class_title"];
$day = $row["day"];
$class_time = $row["class_time"];
$time = $row["time"];
// check which dates match the days of the week and store in an array
for ($i=1;$i<=$n;$i++){
if ($i<10) {
$i = "0" . $i;
}
$day=date("l",strtotime($yearmonth.$i)); //find weekdays
if($day==$dayofclass){
$time = date("H:i",strtotime($row['time']));
$dates[]=$yearmonth.$i;
$datesdata[$yearmonth.$i] = "0";
$timedata[$yearmonth.$i] = $time;
$classiddate[$yearmonth.$i] = $row['classID'];
}
}
}
echo "</table>";
$conn->close();
}
After that, I check for specific reservations (cancelations, irregular reservations, waitlists) and input them into the array:
$lowerlimit = $yearmonth . "01";
$upperlimit = $yearmonth . "31";
$sql = "SELECT AttendanceDB.*, ClassDB.*
FROM StudentDB
INNER JOIN AttendanceDB ON StudentDB.studentid = AttendanceDB.studentid
INNER JOIN ClassDB ON AttendanceDB.classid = ClassDB.classID
WHERE StudentDB.studentid = '$studentid'
AND AttendanceDB.class_time >= '$lowerlimit'
AND AttendanceDB.class_time <= '$upperlimit'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$loopcount = 0;
// store furikae data in the array
while($row = $result->fetch_assoc()) {
$phpdate = strtotime( $row["class_time"] );
$time = date("H:i",strtotime($row['time']));
$mysqldate = date( 'Y-m-d', $phpdate );
$loopcount++;
$mysqldate = $mysqldate . "+" . $loopcount;
// $loopcount++;
// $mysqldate = $mysqldate . "+" . $loopcount;
$previousdate = $mysqldate;
$previousfurikae = $row['furikae'];
if ($row["furikae"] == 3){
$dates[]=$mysqldate;
$datesdata[$mysqldate] = "1";
$timedata[$mysqldate] = $time;
$classiddate[$mysqldate] = $row['classID'];
} elseif ($row["furikae"] == 8 OR $row["furikae"] == 7) {
$dates[]=$mysqldate;
$datesdata[$mysqldate] = "3";
$timedata[$mysqldate] = $time;
} elseif ($row["furikae"] == 2) {
$dates[]=$mysqldate;
$datesdata[$mysqldate] = "2";
$timedata[$mysqldate] = $time;
}
}
}
$conn->close();
Then finally I check the school calendar and input the days off into the array:
$sql = "SELECT *
FROM SchoolScheduleDB
WHERE date >= '$lowerlimit'
AND date <= '$upperlimit'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// store furikae data in the array
while($row = $result->fetch_assoc()) {
$phpdate = strtotime( $row["date"] );
// $time = date("H:i",strtotime($row['time']));
// $mysqldate = date( 'Y-m-d', $phpdate ) . " " . $time;
$mysqldate = date( 'Y-m-d', $phpdate );
$dates[]=$mysqldate;
$datesdata[$mysqldate] = "666";
}
}
$conn->close();
The way I intended it to work was that:
First the regular classes would be input
Then any reservations would overwrite the original plans
And finally the school calendar would overwrite everything
Currently, this functions as it should, but it is limited to displaying 1 result per day, but I would like to be able to display more than 1 result per day for students who come to multiple classes.
Thank you for your help. If I made any mistakes in my question or my question is unclear I will do my best to revise it.
You can make a Sub-Array for each date by using edged brackets:
$data[20180528][] = 'aa';
$data[20180528][] = 'bb';
$data[20180529][] = 'cc';
$data[20180529][] = 'dd';
$data[20180529][] = 'ee';
will give you an Array like this:
20180528 => aa
=> bb
20180529 => cc
=> dd
=> ee

PHP using TIME from database to calculate hours

<?php
require 'dbfunction.php';
$con = getDbConnect();
if (!mysqli_connect_errno($con)) {
$queryStr = "SELECT * " .
"FROM crewlist WHERE crew_name = 'Peter'";
}
$result = mysqli_query($con, $queryStr);
while ($row = mysqli_fetch_array($result)) {
$a = new DateTime($row["start_hour"]);
$b = new DateTime($row["end_hour"]);
$shift1 = $a->diff($b);
$c = new DateTime($row["start_hour2"]);
$d = new DateTime($row["end_hour2"]);
$shift2 = $c->diff($d);
if ($shift1 > 60*60*14) {
echo 'no';
}
?>
I am trying to deduce the difference between my shift timings, with the condition of (for e.g. shift 1 not exceeding 14 hours). Thanks in advance. The fields of my form is using time as the type.
Convert your start date and end date into timestamp and then take difference of both.
$diff = abs($start-$end)
if($diff > 60 * 60 *14 ){
// Your desired statement
}
if that difference exceeds to 60*60*14 then it will exceed to 14 hour.

Date not showing correct in php code

Hey guys take a look over this code. This code is showing current month stats,but if i want to check last month stats instead of this month then what changes i need to do in this small code ?
$date_time_array = getdate(time());
$last_month = $date_time_array["month"];
$this_year = $date_time_array["year"];
$last_mon = $date_time_array["mon"];
$date = mktime(0,0,0,$last_mon,1,$this_year); //The get's the first of March 2009
$links = array();
$newstamp = time() - 3600;
$cpc = 0;
$cpm = 0;
$click = 0;
for($n=1;$n <= date('t',$date);$n++){
$thisdate = $this_year.'-'.$last_mon.'-'.str_pad($n, 2, '0', STR_PAD_LEFT );
$sql = "select * from pub_st_daily where user='$user' && STR_TO_DATE(pdate,'%Y-%m-%d') = '$thisdate' ";
You can do this :
$date = new DateTime("07/30/2015"); //Will give you July 30th
$date_time_array=getdate($date->format("U"));
...
Demo

php - get sum of clicks for past 7 days

I have a table xeon_users_rented, with: clicks0, clicks1, clicks2, clicks3, clicks4, clicks5, clicks6
Each day, clicks0 will increase, and every day at midnight, a cronjob will run, making clicks0 = clicks1 (setting todays clicks, to yesterday clicks), and then set clicks0 to zero.
What I am trying to achieve is I want to make a graph, that shows the sum of clicks0, clicks1 etc., where clicks0 is todays date.
I have the query below:
$data = array();
for ($x = 0; $x <= 6; $x++) {
$date = date("Y/m/d", time() - ($x * 86400));
$queryE = $dbh->prepare("SELECT SUM(clicks$x) FROM xeon_users_rented WHERE user_by=:username");
$queryE->bindParam(":username", $userdata['username']);
$queryE->execute();
$row = $queryE->fetch(PDO::FETCH_ASSOC);
$dates[] = date("Y/m/d", time() - ($x * 86400));
$data[] = ($row['clicks'.$x.''] > 0 ? $row['clicks'.$x.''] : 0);
}
$days = array('Today');
for ($i = 0; $i < 6; $i++) {
$days[$i] = date('d-m', strtotime('-'.($i + 0).' day'));
}
The $days is working perfectly - it will print out today, and the last couple of days.
The $data is not working. It is just printing out:
0,0,0,0,0,0,0
Can someone please help me out here.
The column from your SUM isn't going to be named clicks$x. It will be named something like SUM(clicks1).
Provide an explicit name in the SQL, like
SELECT SUM(clicks$x) as clickSum ...
Then reference it in row as
$row['clickSum']

php/mysql ordered random dates

I found this great function on SO whilst looking for a way to generate random dates between two fixed timestamps:
function randomDate($start_date, $end_date)
{
// Convert to timestamps
$min = strtotime($start_date);
$max = strtotime($end_date);
// Generate random number using above bounds
$val = rand($min, $max);
// Convert back to desired date format
return date('Y-m-d H:i:s', $val);
}
Source and credit
but I am looking for a way for the dates to be generated in order (start date to end date) as I have used it to generate dates to insert into a database.
The problem is my posts are ORDER BY id DESC and using the function "as is" being that they are random the dates end up out of sync.
ie:
post id 4 - date = 2010-07-11 14:14:10
post id 3 - date = 2012-02-22 18:23:21
post id 2 - date = 2011-03-17 13:52:47
post id 1 - date = 2011-08-14 15:33:50
and I need them to be in sync with the post id.
Now your thinking why not change the query to ORDER BY date DESC instead? ...well that would mess up 99% of code I have already written as there are other columns/rows dependent on it being ORDER BY id DESC and so ordering the dates when being inserted into the database is the only solution.
update:
this is what I tried using madfriend code but all dates are the same where have I gone wrong?
function randomDate($startdate, $enddate){
$min = strtotime($startdate);
$max = strtotime($enddate);
$val = rand($min, $max);
return date('Y-m-d H:i:s', $val);
}
$query = "SELECT * FROM foo";
$num = mysql_num_rows(mysql_query($query));
$randate = randomDate('2010-07-12 09:13:40', '2012-06-12 09:13:40');
$dates = array($randate);
for ($i = 0; $i < $num; $i++) {
$dates[] = randomDate($startdate, $enddate);
}
sort($dates);
while($date = array_shift($dates)) {
$update = "UPDATE foo SET date='{$date}'";
mysql_query($update);
}
plus getting
Notice: Undefined variable: startdate
I'm not quite sure whether you are talking about creation or modification of existing rows.
Updates: basic idea here is quite simple. First, count number of posts with SELECT COUNT(*) FROM your_posts_table query. After that:
// $num is number of posts
$dates = array();
for ($i = 0; $i < $num; $i++) {
$dates[] = randomDate($startdate, $enddate);
}
sort($dates); // Sort dates in ascending order
while($date = array_shift($dates)) {
// now $date won't be lower than it was in previous iterations.
// use it to update your table
}
Insertions: If you are talking about insertions and want to make latest post date random but biggest, here's what you do:
First, select last added post date.
Second, call randomDate with $startdate set to the date of last added post.
Last, insert new row with this date.
function randomDate($startdate, $enddate){
$min = strtotime($startdate);
$max = strtotime($enddate);
$val = rand($min, $max);
return date('Y-m-d H:i:s', $val);
}
$query = "SELECT * FROM foo";
$num = mysql_num_rows(mysql_query($query));
$randate = randomDate('2010-07-12 09:13:40', '2012-06-12 09:13:40');
$dates = array($randate);
for ($i = 0; $i < $num; $i++) {
$dates[] = randomDate($startdate, $enddate);
}
sort($dates);
while($date = array_shift($dates)) {
This query updates all rows in one go:
$update = "UPDATE foo SET date='{$date}' ";
mysql_query($update);
}
Probably were wanting to use
$update = "update foo set date='{$date}' where id = (select id from foo where date is not null order by id limit 1)";
(for that to work you need to set each date in the db to null before you start updating: update foo set date=null)
Also you shouldn't be using myslq_query..

Categories