In PHP, compare an array against a field in a MySQL table - php

I've got two tables; one a list of location names, another a list of companies, a field of which stores potentially multiple locations that the company operates in:
id LocationName
1 Aberdeen
2 Dundee
3 Edinburgh
4 Glasgow
idCompany CompanyName Locations
1 CompanyA 1, 2, 3, 4
2 CompanyB 2, 4
3 CompanyC 1
For each company's details page, I want to list the locations in which they operate, displaying the name of each. Eg. for Company B:
Dundee
Glasgow
etc.
Coming from a VB background, I'd just loop through each dataset and compare each to find the matches, but this is in PHP and I can't get it to work:
// Query for specific firm
$sqlCompany= "SELECT * FROM company_details WHERE CompanyID='".$CompanyID."';";
$rstCompany= mysqli_query($conn, $sqlCompany);
$row = mysqli_fetch_assoc($rstCompany);
// Query list of Locations
$sqlLocationNames= "SELECT * FROM Locations ORDER BY LocationName ASC;";
$rstLocationNames= mysqli_query($conn, $sqlLocationNames);
// Explode the field of locations into an array:
$LocationArray = $row["Locations"];
$LocationArray = explode (",", $LocationArray);
for ($i = 0; $i < count($LocationArray); $i++) {
while ($rowLocationNames = mysqli_fetch_assoc($rstLocationNames)) {
if ($LocationArray[$i]==$rowLocationNames["idLocation"]) {
echo $rowLocationNames["LocationName"]."<br />";
}
}
}
Running this for Company A, I'd expect to get the list of four locations from above, but I only get the first location (Aberdeen). I've tried every combination I can think of, to no avail. I need to keep the data structured this way, as I intend having a select multiple for inserting and also editing the data when I can get this working.
Any ideas where I'm going wrong?

Rather than looping the database fetch inside the iteration of the array, which results in there being no data left to read once you come to the second entry in the array (and hence at most one output, as you are seeing), just loop the database fetch and use in_array to determine whether to output the location name:
while ($rowLocationNames = mysqli_fetch_assoc($rstLocationNames)) {
if (in_array($rowLocationNames["idLocation"], $LocationArray)) {
echo $rowLocationNames["LocationName"]."<br />";
}
}

The problem is that your while loop to read the location names from the db is nested within the for loop. After the the first iteration of the for loop, the database pointer is at the end of the recordset, so when you go through the next iteration, there are no records left to read.
Try reading the records in to an array before entering the for loop and then using the while loop to iterate over the newly created array.

Related

Compare php MySQL query result arrays to get assosciated value from one of the arrays

I have one set of results with selected player ID's, and another set of results of all playerID's and the price they will pay and I don't know how to combine the two.
I think the easiest way to explain is to show what I have done so far and what I'm trying to figure out.
I have an input form which gives a dropdown menu (event type) and a list of checkboxes for players:
Event type: Match
X = Player1 Junior
_ = Player2 Senior
X = Player3 Senior
Submitting this gets the player ID's which I can access with this:
foreach ($_POST as $key => $value) {
echo $value;
}
I can then using below query, retrieve the prices that each player within the club would pay for the event, based on the event type and the category of the player.
SELECT prices.price, book.id
FROM prices
JOIN book
ON prices.cat = book.pricecat
WHERE eventType = ?('$eventtype') AND clubID = ?('$clubID')
So now I have these two sets of results
One containing the ID's of selected players.
The other containing all of the clubs playerID's and the Price to be paid for each.
How can I compare the two to get the prices for only the players selected?
Very new to PHP & SQL (4 long days of it!). I'm building the app for personal use and to trial it, need it done when hockey season starts in a week, so not had chance to learn properly from the beginning as I'd want to. Solved many problems but now my head hurts so I'll be very grateful for some advice on how I can solve this one!
Put your two sets of results into two arrays, and then loop through them.
$resultA = (firstset, with selected player names only);
$resultB = (secondset, with all the player names [0] and prices [1]);
$resultC = array(); // our final array that we'll build below
foreach ( $resultA as $selected )
{
foreach ( $resultB as $player )
{
if ( $selected == $player[0] )
{
$resultC[] = $player; // the "[]" adds an element to an array
}
}
}
var_dump($resultC); // show us the final array

Detect when id retrieved from php query is changed

I'm running a query where I'm getting the average score of a student, by getting the average score of an activity type(quiz,exams,etc.) and multiplying it to its assigned grade percentage(ex: 80 *.03).
I've grouped the result by its activity_ID and Student ID.
To get the Grade of the student I need to add the score of each activity type. by simple adding all the result of each activity type.
(ex:grade =10.40+30+12;)
Now my problem is when the student ID is changed the result of the previous student is added to the result of the new one.
(ex:new student grade = previous result, plus his own)
I want to detect when the Student ID is changed inside the
while($row = mysqli_fetch_array($result)) {
$studentID_link = $row['studentID'];
$atName = $row['AT_name'];
$GLOBALS['AR_Score'] = $row['AVG(AR.Score)'];
$AT_gradePercentage =$row['AT_gradePercentage'];
$AT_gradePercentage /=100;
$periodGrades = $AR_Score*$AT_gradePercentage;
$variableName = $variableName + $periodGrades;
}
Use
mysqli_fetch_assoc()
Check for the id after storing the initial student id in a temp variable outside of the loop. Compare each new row's student ID to the previously stored temporary id. Also declare an array outside of the loop and use
array_push()
to push each total onto the array. Use an associative array with the student ID as the key and avoid using array_push if you are accessing student IDs out of order or use an index in mysql to allieviate this issue.
Honestly, you may want to reexamine your sql or show us if you want us to rewrite the code for you.
Update:
If the current mysqli_fetch_array is fetching an associative array, you can leave it, however refer to my above suggestions if you are having issues with that.
$curr_student = NULL;
$array = [];
while($row = mysqli_fetch_array($result)) {
$studentID_link = $row['studentID'];
if($curr_student === NULL || $curr_student !== $studentID_link){
$curr_student = $studentID_link;
if(!array_key_exists($curr_student, $array)) $array[$curr_student] = 0;
}
$atName = $row['AT_name'];
$GLOBALS['AR_Score'] = $row['AVG(AR.Score)'];
$AT_gradePercentage =$row['AT_gradePercentage'];
$AT_gradePercentage /=100;
$periodGrades = $AR_Score*$AT_gradePercentage;
$array[$curr_student] = $array[$curr_student] + $periodGrades;
}
I'm not certain about your global array and how you are using it, but this should work to add your students into each array member regardless of random access of student ID.

What is my last row_number in mysql query?

I have a query like this:
$sql = "SELECT * FROM doctors WHERE city ='$city' LIMIT 10 ";
$result = $db->query($sql);
And I show the result like this :
while($row = $result->fetch_object()){
echo $row->city;
}
The Problem :
Mysql , will search through my database to find 10 rows which their city field is similar to $city.
so far it is OK;
But I want to know what is the exact row_number of the last result , which mysql selected and I echoed it ?
( I mean , consider with that query , Mysql selected 10 rows in my database
where row number are:
FIRST = 1
Second = 5
Third = 6
Forth = 7
Fifth = 40
Sixth = 41
Seventh = 42
Eitghth = 100
Ninth = 110
AND **last one = 111**
OK?
I want to know where is place of this "last one"????
)
MySQL databases do not have "row numbers". Rows in the database do not have an inherent order and thereby no "row number". If you select 10 rows from the database, then the last row's "number" is 10. If each row has a field with a primary id, then use that field as its "absolute row number".
You could let the loop run and track values. When the loop ends, you will have the last value. Like so:
while($row = $result->fetch_object()){
echo $row->city;
$last_city = $row->city;
}
/* use $last_city; */
To get the row number in the Original Table of the last resultant (here, tenth) row, you could save the data from the tenth row and then, do the following:
1. Read whole table
2. Loop through the records, checking them against the saved data
3. Break loop as soon as data found.
Like So:
while($row = $result->fetch_object()){
echo $row->city;
$last_row = $row;
}
Now, rerun the query without filters:
$sql = "SELECT * FROM doctors";
$result = $db->query($sql);
$rowNumber = 0;
while($row = $result->fetch_object()) {
if($row == $last_row) break;
$rowNumber++;
}
/* use $rowNumber */
Hope this helps.
What you can do is $last = $row->id; (or whatever field you want) inside your while loop - it will keep getting reassigned with the end result being that it contains the value of the last row.
You could do something like this:
$rowIndex = 0;
$rowCount = mysqli_num_rows($result);
You'd be starting a counter at zero and detecting the total number of records retrieved.
Then, as you step through the records, you could increment your counter.
while ( $row = $result->fetch_object() ) {
$rowIndex++;
[other code]
}
Inside the While Loop, you could check to see whether the rowIndex is equal to the rowCount, as in...
if ($rowIndex == $rowCount) {
[your code]
}
I know this is a year+ late, but I completely why Andy was asking his question. I frequently need to know this information. For instance, let's say you're using PHP to echo results in a nice HTML format. Obviously, you wouldn't need to know the record result index in the case of simply starting and ending a div, because you could start the div before the loop, and close it at the end. However, knowing where you are in the result set might affect some styling decisions (e.g., adding particular classes to the first and/or last rows).
I had one case in which I used a GROUP BY query and inserted each set of records into its own tabbed card. A user could click the tabs to display each set. I wanted to know when I was building the last tab, so that I could designate it as being selected (i.e., the one with the focus). The tab was already built by the time the loop ended, so I needed to know while inside of the loop (which was more efficient than using JavaScript to change the tab's properties after the fact).

I need some help creating a query and a database table to retroactively assign numbers to existing table

As my info states, I inherited the job of statistician for a local dart league. (Woohoo $20 a season)
I would love to implement an ELO rating system.
The current database table has over 100,000 entries.
There are 3 different games that are played. Singles, Doubles, and Team.
The originator of the database has the games entered as such:
Index Player1_num Player2_num Opp_Player1_num Odd_Player2_num H_team V_team Season Week W L Game_type
A singles game is entered twice.
values(1,20,null,30,null,200,300,11,2,1,0,301_singles)
and
values(2,30,null,20,null,200,300,11,2,0,1,301_singles)
It was done this way to facilitate easier look-ups of individuals.
A doubles game would have values such as
(3,20,21,30,31,200,300,11,2,1,0,501_doubles)
(4,21,20,30,31,200,300,11,2,1,0,501_doubles)
(5,30,31,20,21,200,300,11,2,0,1,501_doubles)
(6,31,30,20,21,200,300,11,2,0,1,501_doubles)
There again, it is built for easier queries for looking up wins and losses across seasons and with different partners.
A team game is:
(7,null,null,null,null,200,300,11,2,1,0,team_game)
So I added a match_num column to the table to help lump the games under 1 number.
However, I am unsure how best to assign the numbers, understandably, I don't feel like going through all 90k entries by hand.
Note: The early seasons were modified by hand and not all double matches have 4 entries (some only have 1). Some matches may be out of order as well (Instead of indexes: 1,2 they could be 1,9).
I don't know if you need more info for this, and I am unsure of how to post larger examples of the table.
Current code:
<body>
<?php
include "inc.php";
// Select Max Match Number
$sqlMatch="select max(match_num) from stats_results";
$match =mysql_query($sqlMatch);
$m= $match ? mysql_result($match,0):mysql_error();
$matchno= $m+1; // First Match number
$game=array("'301_singles'","'cricket_singles'","'501_singles'","'301_doubles'","'cricket_doubles'");
// selects max season
$sqlSeason="select max(season_index) from stats_season";
$season =mysql_query($sqlSeason);
$smax= $season ? mysql_result($season,0):mysql_error();
# $smax=2;
// for each season up to max season
for($s=1;$s<=$smax;$s++)
{
// Selects max week within the current season
$sqlWeek="select max(week) from stats_results where season=$s ";
$Week =mysql_query($sqlWeek);
$wmax= $Week ? mysql_result($Week,0):mysql_error();
# $wmax=2;
// for each week within current season up to the max week
for ($w=1;$w<=$wmax;$w++)
{
// each singles game
foreach($game as $g)
{
###########################################################################################################
$result = mysql_query("SELECT * FROM stats_results where season=$s and week=$w and game_code=$g ;") or die(mysql_error());
// Put them in array
for($i = 0; $rows[$i] = mysql_fetch_assoc($result); $i++) ;
// Delete last empty one
array_pop($rows);
//******************************************************
$matches=array();
foreach($rows as $record)
{
// Get a unique match code for this match
$matchid= getMatchID($record);
// Have we seen this ID before? If yes add this record index to the existing array
// otherwise create an array with just this value
if (!isset($matches[$matchid])) $matches[$matchid]= array($record['index_results']); // No
else $matches[$matchid][]= $record['index_results']; // Yes, add this Index
}
// Now $matches is an array of arrays of Index values, grouped by "match" so...
/* Sort $matches by key (see getMatchID for why!) */
ksort($matches);
// Update the table
foreach($matches as $match)
{
// Create SQL instruction to set the match_num for all the Index values in each entry
$sql= "UPDATE stats_results SET match_num = $matchno WHERE index_results IN (".implode(",", $match).")";
echo "<br>";
echo $sql;
/* Execute the SQL using your chosen method! */
// Move the match count on
$matchno++;
}
// End our loops
}
}
}
function getMatchID($gamerecord)
{
$index= "{$gamerecord['season']}-{$gamerecord['week']}-{$gamerecord['game_code']}-";
$players= array(
$gamerecord['player1_num'],
empty($gamerecord['player2_num'])?0:$gamerecord['player2_num'],
$gamerecord['opp_player1_num'],
empty($gamerecord['opp_player2_num'])?0:$gamerecord['opp_player2_num']
);
// Sort the players to get them in a consistent order
sort($players);
// Add the sorted players to the index
$index.= implode('-', $players);
return $index;
}
?>
</body>
(I'm putting this into an Answer so I can get it to layout a bit better - but it's not really a "solution" as such!)
I think what I'd do is try and build an array of arrays of Index values grouped by game - you can then use that to create SQL to update the table.
So, if $rows is an array of all records we'd do something like the following pseudo-code:
$matches= array();
foreach($rows as $record)
{
// Get a unique match code for this match
$matchid= getMatchID($record);
// Have we seen this ID before? If yes add this record index to the existing array
// otherwise create an array with just this value
if (!isset($matches[$matchid])) $matches[$matchid]= array($record['Index']); // No
else $matches[$matchid][]= $record['Index']; // Yes, add this Index
}
// Now $matches is an array of arrays of Index values, grouped by "match" so...
/* Sort $matches by key (see getMatchID for why!) */
ksort($matches);
// Update the table
$matchno= 1; // First Match number
foreach($matches as $match)
{
// Create SQL instruction to set the match_num for all the Index values in each entry
$sql= "UPDATE games SET match_num = $matchno WHERE Index IN (".implode(",", $match).")";
/* Execute the SQL using your chosen method! */
// Move the match count on
$matchno++;
}
So all that leaves is the getMatchID function - if we give each match a temporary ID based on it's season, week and a sorted list of it's participants (and use the Season and Week first) that should be unique for each game and we can sort by this index later to get the games in the right order. So again in rough pseudo-code, something like:
function getMatchID($gamerecord)
{
$index= "{$gamerecord['Season']}-{$gamerecord['Week']}-{$gamerecord['H_Team']}-{$gamerecord['V_Team']}-";
$players= array(
empty($gamerecord['Player1_Num'])?0:$gamerecord['Player1_Num'],
empty($gamerecord['Player2_Num'])?0:$gamerecord['Player2_Num'],
empty($gamerecord['Opp_Player1_Num'])?0:$gamerecord['Opp_Player1_Num'],
empty($gamerecord['Opp_Player2_Num'])?0:$gamerecord['Opp_Player2_Num']
);
// Sort the players to get them in a consistent order
sort($players);
// Add the sorted players to the index
$index.= implode('-', $players);
return $index;
}
So all being well $index would come back with something like 11-2-200-300-0-0-20-30 for the first singles match in your example - no matter which of the game records we were looking at.
Does that make sense/help at all?

how to get multiple columns from database in one array?

i want that against each numbers, its call_count and duration are saved in single array.. this is my table:
Number Call_count duration
03455919448 4 14
03215350700 2 35
i want somethng like this:
foreach($number as $number1)
{
$data=array($row['call_count']<3,$row['duration']<20,1)
}
basically i want against each number its count and duration are checked for some values and if they meet the condition, display output 1... actually i can do it with simple if-else but as i have to train my dataset for neural network implementaion so all rows must be in one array? can anyone please help me out?
Maybe I don't understand quite well your code, but:
foreach($number as $number1)
$number1 is never used in your foreach :
$data=array($row['call_count']<3,$row['duration']<20,1)
So I guess $number1 is $row.
Second, it would help me if you provide the SQL Statement you are using now.
You could do a query like:
select Number, if(Call_count<3, if(duration<20, 1, 0), 0) as checked from tablename;
This gives you only the number, and 1 if both conditions are met, and 0 otherwise.
After that, in php do a loop (presented in plain mysql* funcions)
$data = array();
while ($row = mysql_fetch_assoc($result)) { // row will be an array with Number and checked as items
$data[] = $row;
}
// at this point you will have all rows in one array, with number and corresponding 1/0 in each item

Categories