I'm trying to improve a php script that prints a list with db values and I need to make some complex (for me) operations to achieve what I want:
A list that prints the months and if they are paid or not, a bonus value with an extra bonus value for the first 3 ids and if the user already received it.
if ($stmt = $mysqli->prepare(" SELECT members.*, account_type.*, friends.*, friendsCount.friendID,
COUNT(friendsCount.friendID) AS num_f
FROM members
INNER JOIN account_type ON account_type.id = ?
INNER JOIN friends ON friends.friendID = ?
INNER JOIN friends AS friendsCount ON friendsCount.userID = ?
WHERE members.id = ?")) {
$stmt->bind_param('iiii', $_SESSION['acc_type'], $_GET['id'], $_SESSION['user_id'], $_GET['id']);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_array();
$monthNames = array("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre");
$paid = array(); //Placeholder for paid months.
for ($i = 1; $i < 13; $i++) {
$month = 'month' . $i;
$bonus_month = 'bonus_month' . $i;
// check if the user received the monthly bonus
if ($row[$bonus_month] == 0) {
// check if the friend's member account is active
if ($row['status'] == 1) {
// check if the friend paid the month
if ($row[$month] == 1) {
$paid[] = 'Pagado';
// check the user account type
if ($row['type'] == 'Base') {
// TODO: check if the friend is one of the three first (special promotion)
// (user gets double bonus for the first three invited friends)
if ($row['extra'] == 1) {
$extra = $row['bonus'] + 5;
$bonus[] = $extra . '€';
}
else {
$bonus[] = $row['bonus'] . '€';
}
}
else {
$bonus[] = $row['bonus'] . '€';
}
$cashed[] = 'No';
$non_cashed[] = $bonus[];
}
else {
$paid[] = 'No Pagado';
$bonus[] = 'n/a';
$cashed[] = 'n/a';
}
}
else {
$paid[] = 'n/a';
$bonus[] = 'n/a';
$cashed[] = 'n/a';
}
}
else {
$paid[] = 'Pagado';
$bonus[] = $row[$bonus_month] . '€';
// TODO: find a way to check if user already received the bonus
// 12 new columns? (bonus_received_month1-12)
if (1 == 0) {
$cashed[] = 'Si';
$total_cashed[] = $row[$bonus_month];
}
else {
$cashed[] = 'No';
$non_cashed[] = $row[$bonus_month];
}
}
}
//Now make the HTML list
foreach ($monthNames as $key => $month) {
echo '
<div class="list">
<ul>
<li><a class="month">' . $month . '</a></li>
<li><a class="status">' . $paid[$key] .'</a></li>
<li><a class="bonus">' . $bonus[$key] . '</a></li>
<li><a class="cashed">' . $cashed[$key] . '</a></li>
</ul>
</div>';
}
} else echo $mysqli->error;
Actually it's working quite well but somethings are not implemented yet:
1º The extra bonus value for the first 3 ids (not including the status 0 accounts).
2º A way to check if the user already received the bonus so can be displayed the balance and the total received:
First of, I'd like to improve the method that adds the extra bonus:
// this column contains 1 for the first 3 friendIDs
if ($row['extra'] == 1) {
$extra = $row['bonus'] + 5;
$bonus[] = $extra . '€';
} else $bonus[] = $row['bonus'] . '€';
To achieve this: I have to check for the first 3 friendIDs (where userID = $_SESSION[user_id]) and compare if one of those match the current $_GET['id'].
// the number of friends
$count = $row['num_f'];
// the current friendID
$f_id = $_GET['id'];
$match = 'the first 3 ids (with acc status 1)';
if ($count > 2 && $f_id == $match) {
$extra = $row['bonus'] + 5;
$bonus[] = $extra . '€';
} else $bonus[] = $row['bonus'] . '€';
And statistics info:
// not received
echo '<p>Total acumulado: ' . array_sum($non_cashed[]) . '€</p>';
// total received
echo '<p>Total recibido: ' . array_sum($total_cashed[]) . '€</p>';
The big problem that I'm facing here is: If one of the three first accounts is inactive (status 0) how to "take" the next one that is active...
If account 1 is inactive but 2 and 3 are not, the account number 4 should be eligible for the extra bonus. The numbers are just the order that come from "select friendID from friends where userID = ?"
I presume that I can use array_key_exists to check if the $f_id exist inside the array that contains the first 3 ids...
How can I make that? Sorry if I made some mistakes, I'm working for several hours.
The tables are:
1º members: get the friend info -> "id", "status" (0 or 1; inactive/active), "name" and "month1-12" (12 columns: 0 or 1; not paid / paid month)
2º account_type: get the user acc type and the bonus value -> "id" (members.acc_type), "type" (the type name) and "bonus" (5, 10, 15 etc...)
3º friends: get the user info related to his friend -> "friendID" (members.id, the invited user), "userID" (members.id, the user that invited a friend), "extra" (1 for the first 3 invited users and 0 for the rest; 1 is double bonus, 0 is normal bonus. This column is going to be deleted), "bonus_month1-12" (12 columns; 0 is for the current month or a future month, 1+ is the bonus the user gained this month)
And to check if the user already received the bonus, I'm thinking to add 12 more columns to know it. It'll be 0 for non-received and 1 for received, unless a better method is suggested :)
Related
I know there are similar questions already, but I can't find a clear and simple answer.
I have this query :
"SELECT dbo.tbTransaction.dateHeure, dbo.tbTransaction.Etat, dbo.tbPoste.nomPoste
FROM dbo.tbTransaction
INNER JOIN dbo.tbPoste ON dbo.tbTransaction.ID_poste = dbo.tbPoste.ID_POSTE
WHERE dbo.tbPoste.id_site LIKE 47
AND dbo.tbPoste.nomPoste LIKE '0909_CLIENT'
AND dateHeure >= DATEADD(dd, DATEDIFF(dd,0,GETDATE()), 0)
ORDER BY dateHeure DESC";
It enables me to fetch all the database insertions of the day(>= DATEADD(dd, DATEDIFF(dd,0,GETDATE()), 0)) on a particular post (0909_CLIENT), sorted by the most recent time of insertion(ORDER BY dateHeure DESC).
I would like to be able to retrieve the number of inserts per hour, the goal is to be able to generate live graphics hour by hour.
I manage to get the total number of insertions during the day with :
$params = array();
$options = array( "Scrollable" => SQLSRV_CURSOR_KEYSET );
$result = sqlsrv_query( $conn, $sql , $params, $options );
$row_count = sqlsrv_num_rows( $result ). PHP_EOL;
echo '<br>';
if ($row_count === false)
echo "Error in retrieveing row count;
else {
echo $row_count;
}
I can see the lines entered in the database at a particular time with :
$five = "05:";
$six = "06:";
$seven = "07:";
if ($result === false) {
die(print_r(sqlsrv_errors(), true));
} else {
while ($row = sqlsrv_fetch_array($result)) {
$heureformate = $row["dateHeure"]->format('H:i');
if (strpos($heureformate, $five) !== false) {
echo $heureformate;
echo '<br>';
//count(array($heureformate));
} elseif (strpos($heureformate, $six) !== false) {
echo $heureformate;
echo '<br>';
} elseif (strpos($heureformate, $seven) !== false) {
echo $heureformate;
echo '<br>';
}
}
}
But as I told you, I don't manage to get the number of lines entered per hour and it's this number that interests me to create graphics.
If you have any ideas on how to get this number in SQL or PHP, please help me.
Do you want aggregation?
select datepart(hour, t.dateheure), count(*) as cnt
from dbo.tbtransaction t
inner join dbo.tbposte p on t.id_poste = p.id_poste
where p.id_site = 47 and p.nomposte = '0909_client' and t.dateheure >= cast(gedate() as date)
group by datepart(hour, dateheure)
This filters the dataset for rows whose dateheure belongs to the current day, and counts how many records there is in each hour.
Note that I simplified the date filtering logic, and turned the like conditions to equalities (since no wildcards are involved, both are equivalent).
I have a PHP/MySQL query that returns the following:
array ( 'name' => 'Jess', 'month' => '2020-03-31 12:28:00', 'count' => '1', )
array ( 'name' => 'Bob', 'month' => '2020-04-31 12:28:00', 'count' => '2', )
array ( 'name' => 'Tom', 'month' => '2020-05-31 12:28:00', 'count' => '2', )
array ( 'name' => 'Bob', 'month' => '2020-05-31 12:28:00', 'count' => '2', )
The months return in an ordered fashion (E.g. January records are always before February records).
However, not every user will have a result every month (see above).
And I want my data to present such as this, in an html table:
Month Jess Bob Tom
March 1
April 2
May 2 2
Here is my (non working) attempt:
<?php
/*loop through all customers and print out each induvidual users performance*/
$con = mysqli_connect("localhost","root","","perfmon");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
exit();
}
//main query for customer names
if ($customers = mysqli_query($con, "SELECT Distinct(customer_name) FROM slog ORDER BY customer_name DESC;")) {
while($row=mysqli_fetch_assoc($customers))
{
$name = $row["customer_name"];
print("<b>".$name." </b><br>");
$total = 0;
$cur_month = NULL;
$namepos = array();
$th = "<th>Month</th>";
$tr = "";
$npcount = 0;
//Loop over the customer names, and pull the modified count per user.
if ($user_perf = mysqli_query($con, "select modified_by as name, created_date as month, count(modified_by) as count from slog where customer_name = '$name' group by modified_by, MONTH(created_date) order by month;")) {
while($row=mysqli_fetch_assoc($user_perf))
{
//Assign variables from mysql results
$month = date("F",strtotime($row["month"]));
$name = $row["name"];
$count = $row["count"];
$total += $row["count"];
//Only add the month once!
if($cur_month != $month){
$cur_month = $month;
$tr .= "</tr><tr><td>" . $cur_month. "</td>";
//print($cur_month . "<br>");
}
//store the username 'position' to build a table (this determines how many spaces are needed.)
if(!array_key_exists($name,$namepos))
{
$namepos[$name] = $npcount;
$npcount += 1;
$th .= "<th>" .$name . "</th>";
}
//add details to tr in correct pos
for( $i = 0; $i < $namepos[$name]; $i++){
$tr .= "<td></td>";
}
$tr .= "<td> ".$count." </td>";
//print(" ".$name . " " . $count . " <br>");
}
print("<table border='1'><tr>". $th . "</tr>" . $tr . "</table>");
print("<br>Total: ".$total." <br><br> ");
mysqli_free_result($user_perf);
}
}
mysqli_free_result($customers);
}
mysqli_close($con);
?>
Which unfortunately results in results such as this:-
What would be the best way to achieve this?
I have tried storing the position of each user in the table headers, but then it is difficult to know how many empty columns to add before and the entry (see image above).
just a quick update. I have managed to get what I desired through the following code
<?php
/*loop through all customers and print out each induvidual users performance*/
$con = mysqli_connect("localhost","root","","perfmon");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
exit();
}
//main query for customer names
if ($customers = mysqli_query($con, "SELECT Distinct(customer_name) FROM slog ORDER BY customer_name DESC;")) {
while($row=mysqli_fetch_assoc($customers))
{
//Name of customer
$name = $row["customer_name"];
//Print customer name
print("<b>".$name." </b><br>");
//Used to display total jobs
$total = 0;
$user_list = array("Month");
$monthlist = array();
$st_array = array();
//Loop over the customer names, and pull the modified count per user.
if ($user_perf = mysqli_query($con, "select modified_by as name, created_date as month, count(modified_by) as count from slog where customer_name = '$name' group by modified_by, MONTH(created_date) order by month;")) {
while($row=mysqli_fetch_assoc($user_perf))
{
$month = date("F",strtotime($row["month"]));
$name = $row["name"];
$count = $row["count"];
$total += $row["count"];
//make our left column (months)
if(!in_array($month, $monthlist)){
array_push($monthlist, $month);
}
//Collect all unqiue users, to make our headers array. also stores the order theyre in.
if(!in_array($name, $user_list)){
array_push($user_list, $name);
}
//make a 2d array of all data
$tmp = [$month, $name, $count];
array_push($st_array, $tmp);
}
/**Process fetched data **/
$row = "";
$previous_pos = 1;
$fe = True;
//Print each unique user as a table header
print("<table border='1'>");
print("<tr>");
foreach ($user_list as $th){
print("<th>".$th."</th>");
}
print("</tr>");
//Loop the month array
foreach ($monthlist as $td){
//Loop the user array
foreach ($user_list as $usr){
//Loop our "2d" array (an array containing Month,User,Count)
foreach($st_array as $array_2d){
//If we match the correct month and user, return the count value. This ensures the users return in the correct order.
if ($array_2d[0] == $td && $array_2d[1] == $usr){
//Pos - Get the current position of the selected user.
//Establish how many empty entries need to come before. E.g. User in col 1 has no empty entries infront. User in column2 has 1 entry empty infront (if column 1 is empty).
$pos = array_search($usr, $user_list);
if ($previous_pos != $pos){
$row .= str_repeat("<td>0</td>", ($pos-$previous_pos-1));
}
//Assign our previous position
$previous_pos = $pos;
//If our first entry isn't in column 1, add an extra 0.
if($pos!==1 && $fe)
$row .= "<td>0</td>";
$fe = False;
//Add the data
$row .= "<td>".($array_2d[2])."</td>"; //change to [1] for debug
}
}
}
//Print the table row.
print("<tr><td>".$td ."</td>" . $row ."</tr>");
//Reset our variables.
$row = "";
$fe=True;
$previous_pos = 1;
$first_result = True;
}
print("</table></br>");
mysqli_free_result($user_perf);
}
}
mysqli_free_result($customers);
}
mysqli_close($con);
?>
Essentially I created 3 arrays. An array of users, an array of months, and an array of all data (3d array). I use the months and users to record the order in which the tables should be presented. I then loop through my 3d array and print the relevant data.
Despite the downvotes, I would like to thank you all for offering your help. If you have any recommendations please let me know.
I'm not sure what to do when my if statement is true and how to count each hit.
My code first checks a table to get all the companies that are active.
I then want to go to each table for that company that is active, get the last entry, and count how many values for Status are either not equal to 3(!=3) or equals 2(==2).
I have no problems with this code giving me values from the row for each company but I'm not sure how to count this.
// Get a list of active companies
$sql_companyinfo="SELECT Name FROM Company_Info Where Active=True ORDER BY Name";
$result_companyinfo = mysqli_query($conn, $sql_companyinfo);
// Create variables and Loop for each active Company
while($prop_info = mysqli_fetch_assoc($result_companyinfo)) {
$prop_name = $prop_info["Name"];
$company_table = ("Company_" . "$prop_name");
// Query Table and get the last record added
$result_company = mysqli_query($conn,"SELECT * FROM $company_table WHERE ID=(SELECT MAX(ID) FROM $company_table)");
$row1 = mysqli_fetch_array($result_company);
//Status from Last Row Inserted
$Row_Status = $row1['Status'];
// This is where I get lost. For each company I need to know how many companies where $Row_Status != 3 or == 2
if ($Row_Status != '3') {
// Start with 0 and add 1 for each match
for($n3 = 0; $array[$n3]; $n3++) {
$n3_result = $n3;
}
} elseif ($Row_Status == '2') {
// Start with 0 and add 1 for each match
for($e2 = 0; $array[$e2]; $e2++) {
$e2_result = $e2;
}
{
echo "ERROR: Could not execute";
}
}
}
echo $n3_result;
echo $e2_result;
How to creating a loop that checks several tables and counts the results depending on value?
See you can do like this na:-
$Row_Status = '2';
if ($Row_Status != '3') {
echo 'ok1';
} else {
if ($Row_Status == '2') {
echo 'ok2';
} else {
echo 'ok3';
}
}
I feel this is a more logic problem than anything. A database has pictures saved via a source reference and booleans for tags e.g. isLandscape=1. I had made a system to traverse pages of results based on types asked. The following is an example of what I'm facing. I only see the same 12 pictures from page 0 -> page 22. Then I start to see new ones. I think I have just been overlooking this bug since I had not noticed it until now. One thing I noticed was page22*12pictures = 264 which is the same as the first new picture id that is seen. You can see the error here (just change the p to different pages).
<?php
$pictureid = -1;
$startpage = 0;
$viewsection = -1;
$uid = -1; //user id
$amntperrow = 4; //how many pictures per row, must correlate with doThumb()'s switch case amounts
$maxrows = 3; //how many rows of pictures to drop
if(isset($_GET['pid']) && is_int(intval($_GET['pid']))) $pictureid = clean($_GET['pid']);
if(isset($_GET['sec']) && is_int(intval($_GET['sec']))) $viewsection = clean($_GET['sec']);
if(isset($_GET['p']) && is_int(intval($_GET['p']))) $startpage = clean($_GET['p']);
$result = generateResult(array("isFlowers"), $startpage);
//**snip** -- drawing thumbnails would happen here
function generateResult($types, $page) {
global $amntperrow;
global $maxrows;
$sqlWheres = "";
$idAmnt = ($amntperrow*$maxrows)*$page;
if(isset($types) && !empty($types)) {
if(count($types) >= 1) {
for($i = 0; $i<count($types); $i++) {
$sqlWheres .= $types[$i] . "='1'";
if($i < count($types)-1) $sqlWheres .= " AND ";
}
}
}
$result = "SELECT * FROM pictures WHERE ";
if(!empty($sqlWheres)) $result .= $sqlWheres . " AND " ;
$result .= " private='0' AND id >='" . $idAmnt . "' LIMIT " . ($amntperrow*$maxrows);
return $result;
}
?>
This seems like a glaring bug that I am overlooking. Thanks for the help.
What is the difference between these two queries?
SELECT *
FROM pictures
WHERE private = '0' AND id >= '24'
LIMIT 12;
and
SELECT *
FROM pictures
WHERE private = '0' AND id >= '36'
LIMIT 12;
Answer: potentially no difference at all. The database engine can decide in either case that it wants to return pictures with ids 100 through 111 - that result set meets all of the conditions of either query.
Try a query like this instead:
"SELECT *
FROM pictures
WHERE private = '0'
ORDER BY id
LIMIT " . $idAmnt . ", " . ($amntperrow * $maxrows)
The ORDER BY id is really the key. Paging through database results is generally done with a combination of ORDER BY and LIMIT.
I'm currently experiencing a memory usage issue - but I cannot figure out where. I've tried replacing some of my foreach loops with for loops or by issuing another query to the DB, but I am still gettting the same error - "Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) in on line 109". Can anyone provide some insight as to what may be causing the issue? Thank you!
Code after #Patrick 's answer:
$participating_swimmers = array();
$event_standings = array();
$qualifying_times = array();
$events = array();
$current_event = '';
$select_times_sql = "SELECT event, time, name, year, team, time_standard, date_swum
FROM demo_times_table
WHERE sex = 'M' AND (time_standard = 'A' OR time_standard = 'B')
ORDER BY event, time ASC";
$select_times_query = mysql_query($select_times_sql);
//Create array with the current line's swimmer's info
while ($swimmer_info = mysql_fetch_assoc($select_times_query)) {
if($current_event != $swimmer_info['event']){
$events[] = $current_event = $swimmer_info['event'];
}
//Create array with the current line's swimmer's info
$swimmer_info["time"] = $select_times_row['time'];
$swimmer_info["name"] = $select_times_row['name'];
$swimmer_info["year"] = $select_times_row['year'];
$swimmer_info["team"] = $select_times_row['team'];
$swimmer_info["time_standard"] = $select_times_row['time_standard'];
$swimmer_info["date_swum"] = $select_times_row['date_swum'];
//Create "Top 8" list - if more than 8 A cuts, take them all
if (($swimmer_info["time_standard"] == "A") || ($swimmer_info["time_standard"] == "B")) {
//Check if there are 8 or less entries in the current event, or if the swim is an A cut
if ((count($event_standings[$current_event]) < 8) || ($swimmer_info["time_standard"] == "A")) {
//Add swimmer to the list of invites
$event_standings[$current_event][] = $swimmer_info;
//Keep only the identifying information about the swimmer
$condensed_swimmer_info["name"] = $swimmer_info["name"];
$condensed_swimmer_info["year"] = $swimmer_info["year"];
$condensed_swimmer_info["team"] = $swimmer_info["team"];
//Check if swimmers name already appears in list
if (!in_array($condensed_swimmer_info, $participating_swimmers)) {
//It is a unique user - add them to the list
$participating_swimmers[] = $condensed_swimmer_info;
}
} else {
//Add the qualifying time that did not fit into the list to a list of qualifying times
$qualifying_times[$current_event][] = $swimmer_info;
}
}
}
//Sort each array of times in descending order
arsort($event_standings);
arsort($qualifying_times);
$num_of_swimmers = count($participating_swimmers);
while ($num_of_swimmers < 80) {
foreach ($events as $loe) {
$num_of_qualifying_times = count($qualifying_times[$loe]);
$swimmer_info = $qualifying_times[$loe][$num_of_qualifying_times-1];
$event_standings[$loe][] = $swimmer_info;
//Keep only the identifying information about the swimmer
$condensed_swimmer_info["name"] = $swimmer_info["name"];
$condensed_swimmer_info["year"] = $swimmer_info["year"];
$condensed_swimmer_info["team"] = $swimmer_info["team"];
//Check if swimmers name already appears in list
if (!in_array($condensed_swimmer_info, $participating_swimmers)) {
//It is a unique user - add them to the list
$participating_swimmers[] = $condensed_swimmer_info;
}
//Remove time from array of qualifying times
unset($qualifying_times[$loe][$num_of_qualifying_times-1]);
}
$new_num_of_swimmers = count($participating_swimmers);
if($num_of_swimmers == $new_num_of_swimmers) break;
else $num_of_swimmers = $new_num_of_swimmers;
}
arsort($event_standings);
arsort($qualifying_times);
foreach($event_standings as $loe => $event_swimmer) {
echo "<h1>",$loe,"</h1><br />";
foreach ($event_swimmer as $es) {
echo $es["time"]," ",$es["name"]," ",$es["team"],"<br />";
}
}
Large data in database is the problem 95% !
- try using limit x,y in your queries , and put those queries in some loop .
- see http://php.net/manual/en/function.mysql-free-result.php it might help
<?php
$participating_swimmers = array();
$event_standings = array();
$qualifying_times = array();
$select_times_sql = "SELECT *
FROM demo_times_table
WHERE sex = 'M'
ORDER BY time ASC";
$select_times_query = mysql_query($select_times_sql);
while ($select_times_row = mysql_fetch_assoc($select_times_query)) {
//Create array with the current line's swimmer's info
$swimmer_info["time"] = $select_times_row['time'];
$swimmer_info["name"] = $select_times_row['name'];
$swimmer_info["year"] = $select_times_row['year'];
$swimmer_info["team"] = $select_times_row['team'];
$swimmer_info["time_standard"] = $select_times_row['time_standard'];
$swimmer_info["date_swum"] = $select_times_row['date_swum'];
//Create "Top 8" list - if more than 8 A cuts, take them all
if (($swimmer_info["time_standard"] == "A") || ($swimmer_info["time_standard"] == "B")) {
//Check if there are 8 or less entries in the current event, or if the swim is an A cut
if ((count($event_standings[$current_event]) < 8) || ($swimmer_info["time_standard"] == "A")) {
//Add swimmer to the list of invites
$event_standings[$current_event][] = $swimmer_info;
//Keep only the identifying information about the swimmer
$condensed_swimmer_info["name"] = $swimmer_info["name"];
$condensed_swimmer_info["year"] = $swimmer_info["year"];
$condensed_swimmer_info["team"] = $swimmer_info["team"];
//Check if swimmers name already appears in list
if (!in_array($condensed_swimmer_info, $participating_swimmers)) {
//It is a unique user - add them to the list
$participating_swimmers[] = $condensed_swimmer_info;
}
} else {
//Add the qualifying time that did not fit into the list to a list of qualifying times
$qualifying_times[$current_event][] = $swimmer_info;
}
}
}
mysql_free_result($select_times_query);
//Sort each array of times in descending order
arsort($event_standings);
arsort($qualifying_times);
$num_of_swimmers = count($participating_swimmers);
$sql = "SELECT DISTINCT(event)
FROM demo_times_table
WHERE sex = 'M' limit 80";
$query = mysql_query($sql);
while ($row = mysql_fetch_assoc($query)) {
$loe = $row['event'];
$num_of_qualifying_times = count($qualifying_times[$loe]);
$event_standings[$loe][] = $qualifying_times[$loe][$num_of_qualifying_times-1];
//Keep only the identifying information about the swimmer
$condensed_swimmer_info["name"] = $qualifying_times[$loe][$num_of_qualifying_times]["name"];
$condensed_swimmer_info["year"] = $qualifying_times[$loe][$num_of_qualifying_times]["year"];
$condensed_swimmer_info["team"] = $qualifying_times[$loe][$num_of_qualifying_times]["team"];
//Check if swimmers name already appears in list
if (!in_array($condensed_swimmer_info, $participating_swimmers)) {
//It is a unique user - add them to the list
$participating_swimmers[] = $condensed_swimmer_info;
}
//Remove time from array of qualifying times
unset($qualifying_times[$loe][$num_of_qualifying_times-1]);
}
$num_of_swimmers = count($participating_swimmers);
mysql_free_result($query);
arsort($event_standings);
arsort($qualifying_times);
$sql = "SELECT DISTINCT(event)
FROM demo_times_table
WHERE sex = 'M'";
$query = mysql_query($sql);
while ($row = mysql_fetch_assoc($query)) {
$loe = $row['event'];
echo "<h1>".$loe."</h1><br />";
foreach ($event_standings[$loe] as $es) {
echo $es["time"]." ".$es["name"]." ".$es["team"]."<br />";
}
}
/*
foreach ($participating_swimmers as $ps) {
echo $ps["name"]."<br /><br />";
}
echo "<br /><br />";
*/
?>
Instead of doing a query within a query, with the potential for logic holes that create a never-ending loop, you can condense it into a single query. For your first block, both loops are just checking for the current event and the sex of the participant, right? So:
$result = SELECT * FROM <my database> WHERE sex = 'M' ORDER BY time ASC
Then you can pull whichever rows you want during the while ($row = mysql_fetch_assoc($result)) loop and compensate for non-distinct values in another way.
One other source of the never-ending loop could be in the block where you sort the qualifying times. You're using "unset" after each, which could be getting the pointer stuck. You could try adding array_values($qualifying_times) after the unset to reindex the array.
Frist off, lose the SELECT DISTINCT like so:
$events = array()
$current_event = '';
$select_times_sql = "SELECT event, time, name, year, team, time_standard, date_swum
FROM demo_times_table
WHERE sex = 'M' AND (time_standard = 'A' OR time_standard = 'B')
ORDER BY event, time ASC";
$select_times_query = mysql_query($select_times_sql);
//Create array with the current line's swimmer's info
while ($swimmer_info = mysql_fetch_assoc($select_times_query)) {
if($current_event != swimmer_info['event']){
$events[] = $current_event = $swimmer_info['event'];
}
//Create "Top 8" list - if more than 8 A cuts, take them all
//Check if there are 8 or less entries in the current event, or if the swim is an A cut
This also loses a bit of redundant code, and can speed up the final output (note the commas in the echo statements - the string doesn't need to be concatenated before it is spat out)
foreach($event_standings as $loe => $event_swimmer) {
echo "<h1>",$loe,"</h1><br />";
foreach ($event_swimmer as $es) {
echo $es["time"]," ",$es["name"]," ",$es["team"],"<br />";
}
}
The final problem lies in the second while loop, where the info being put into $condensed_swimmer_info doesn't have the -1 in place, thus is always blank, and $num_of_swimmers never rises to more than 1 over its original value:
while ($num_of_swimmers < 80) {
foreach ($events as $loe) {
$loe = $row['event'];
$num_of_qualifying_times = count($qualifying_times[$loe]);
$swimmer_info = $qualifying_times[$loe][$num_of_qualifying_times-1];
$event_standings[$loe][] = $swimmer_info;
//Keep only the identifying information about the swimmer
$condensed_swimmer_info["name"] = $swimmer_info["name"];
$condensed_swimmer_info["year"] = $swimmer_info["year"];
$condensed_swimmer_info["team"] = $swimmer_info["team"];
//Check if swimmers name already appears in list
if (!in_array($condensed_swimmer_info, $participating_swimmers)) {
//It is a unique user - add them to the list
$participating_swimmers[] = $condensed_swimmer_info;
}
//Remove time from array of qualifying times
unset($qualifying_times[$loe][$num_of_qualifying_times-1]);
}
$new_num_of_swimmers = count($participating_swimmers);
if($num_of_swimmers == $new_num_of_swimmers) break;
else $num_of_swimmers = $new_num_of_swimmers;
}