I am calling data from an SQL database in PHP, and I want to be able to count the number of specific values I am pulling from the database, I can pull a specific value, and get say 20 values, when I try to get the 'Count' of these values, it'll display 20 '1's so "11111111111111111111" rather than "20".
I have tried printing it, and entering it into a table, and neither produce the result I want.
My code below:
date_default_timezone_set('Europe/London');
$conn = new mysqli("xxx.xxx.xxx","title","password","title");
if (!$con){
{exit("Connection Failed: " . $con);}
//Connecting to the (DB) Database
}
<?php
if (isset($_POST['submit'])){
?>
<table>
<tr><td><strong>Count</strong></td></tr>
<?php
$start=$_POST['start'];
$end=$_POST['end'];
$sql="SELECT Data.Items ".
//Selecting the required data from the table
$sql="FROM Data ";
//Selecting FROM the Table(s) required
$reports = $con->query($sql);
while ($report = $reports->fetch_object()){
$result = count ($report->Items);
echo count ($result);
echo "<tr><td>".$report->Items."</td></tr>";
}
?>
Its because you are using the count function inside a loop as you fetch each row. Each row has got 1 item(which is not even an array). You have to use
echo $reports->num_rows;
before the while loop instead.
You need to take an array with values and count how much time each value is there in database:
You can do this by using array_count_values()
$items = [];
while ($report = $reports->fetch_object()){
$items[] = $report->Items;
}
if (! empty($items)) {
$numOccurances = array_count_values($items);
foreach ($numOccurances as $val => $count) {
echo "<tr><td>" . $count . " times </td><td> => ".$val."</td></tr>";
}
}
Sample Output:
4 times => item 1
2 times => item 2
1 times => item 3
1 times => item 5
2 times => item 6
Related
Basically I am creating a simple music player in PHP and I am setting the id of each song that is played in an array. I have a script which pulls a random number and plays the song with the corresponding id. I want to make it so that if the song has already played that it wont play again.
Currently I have it generate a random number, and if that number has already been played then it adds 1 to the random number.
The problem is if the number that is the result of adding 1 to the random number, it will then play that song again. I was attempting to store the songs played in an array and just increment the number until it doesn't exist in the array but I am struggling to find a solution to the problem.
My code is as follows:
<?php
session_start();
$con=mysqli_connect("blah blah blah");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
if (!isset($_SESSION['played'])) {
$_SESSION['played'] = array();
}
$result = mysqli_query($con,"SELECT * FROM Data") ;
$num_rows = mysqli_num_rows($result);
$numsongs= .20 * $num_rows;
$numsongs=floor($numsongs);
$music = rand(1,$numsongs);
if (in_array($music, $_SESSION['played'])) {$music = $music+1;};
/* goes on to play music below */
$_SESSION['played'][] = $music;
?>
I didn't put my whole script in, the script works minus the repeating of songs. I only included a snippet of how I wrote the repeating script to give an idea of how I attempted it.
Thanks in advance!
I think you are looking for this...
$music = rand(1,$numsongs);
while(in_array($music, $_SESSION['played'])){
$music = $music+1;
echo 'in array '.$music;
}
echo 'Not in array '.$music;
AHAAA!! I figured it out! I ended up using switch() but in a different form.
if (empty($_SESSION['played1'])) {
for ($i = 1; $i <= $numsongs; ++$i) {
$_SESSION['played1'][] = $i;}}
shuffle($_SESSION['played1']);
$music1= $_SESSION['played1'][0];
$result = mysqli_query($con,"SELECT * FROM Data WHERE position = '$music1'") ;
while($row = mysqli_fetch_array($result)){
$del_val=$row[position];
if(($key = array_search($del_val, $_SESSION['played1'])) !== false) {
unset($_SESSION['played1'][$key]);}
Basically created an array between 1 and 10. Then used switch() to randomize the array. Then picked the first number in the array, used it in mysqli query, and then removed it from the array. Problem Solved!!
I'm trying very hard to display this multi dimentional array for past 3 to 4 days to no avail.
All I need to do is to display like below:
carName:
carImage:
days:
amount: // this is where I'm facing the problem to display all the days and amount related to specific car..One car will have few days and amount quoted for each day.
//pls look at my code and help... Thanks
<?php
mysql_select_db($database);
$query_showall = "SELECT rental.*,
car_name.*,
gallery.*,
car_make.*
FROM rental,
car_name,
gallery,
car_make
WHERE car_name.carName_id = gallery.carName_id
AND car_name.carMake_id = car_make.carMake_id
AND rental.carName_id = car_name.carName_id
GROUP BY rental.carName_id";
$result_showall = mysql_query($query_showall) or die(mysql_error());
while($row_showall = mysql_fetch_array($result_showall)) {
$carMake_all = $row_showall['carName'];
$carmake_1[$row_showall['carName_id']][] = $row_showall;
}
foreach($carmake_1 as $make_1=>$name_1) {
foreach($name_1 as $n_1) {
echo $n_1['carName'].'<br/>';
echo $n_1['gallery'].'<br/>';
/* I need to loop through the rental table
to retrieve num of days and amount for
each car here.. */
echo $n_1['rental_days'].'<br/>';
echo $n_1['rental_amount'].'<br/>';
}
}
?>
edit without GROUP BY But how can I stop the carName and imageName not to repeat ?
<?php
mysql_select_db($database);
$query_showall="SELECT rental.*,car_name.*,gallery.*,car_make.* FROM rental,car_name,gallery,car_make WHERE car_name.carName_id=gallery.carName_id AND
car_name.carMake_id=car_make.carMake_id AND rental.carName_id=car_name.carName_id ORDER BY rental_days ASC";
$result_showall=mysql_query($query_showall)or die(mysql_error());
while($row_showall=mysql_fetch_array($result_showall))
{
$carMake_all=$row_showall['carName'];
$carmake_1[$row_showall['carName_id']][]=$row_showall;
}
foreach($carmake_1 as $make_1=>$name_1)
{
foreach($name_1 as $n_1)
{
echo $n_1['carName'].'<br/>';
echo $n_1['gallery'].'<br/>';
echo $n_1['rental_days'].'<br/>';
echo $n_1['rental_amount'].'<br/>';
}
}
?>
Okay, I'll take a shot at this. What I would do is rebuild the array before you try to dump it out so that all your data is organized the way you want it to display, that way at each step of the foreach you can only display what you want.
This code would use your SQL statement without the group by, which as you stated is including all the data.
// Start with an empty array...
$cars = array();
// Loop over all your results
while($row_showall = mysql_fetch_array($result_showall)) {
// Set name, if the ID comes up again, it will be reset but won't hurt anything
$cars[$row_showall['carName_id']]['name'] = $row_showall['carName'];
// Set gallery, if the ID comes up again, it will be reset but won't hurt anything
$cars[$row_showall['carName_id']]['gallery'] = $row_showall['gallery'];
// Now, we add a new property called 'details' and put a new array in...
$cars[$row_showall['carName_id']]['details'][] = array(
// Storing a unique day
'days' => ['rental_days'],
// And a unique amount
'amount' => ['rental_amount']
);
}
// Loop over each entry in our array...
foreach($cars as $car) {
// Print out the name, once
echo $car['name'] . '<br />';
// Print out the gallery, once
echo $car['gallery'] . '<br />';
// Loop over all the details...
foreach($car['details'] as $detail) {
// Print out each day
echo $detail['days'] . '<br />';
// Print out each amount
echo $detail['amount'] . '<br />';
}
}
I'm working on a search system for my database where I break the search phrase into individual search words, search my mySQL database keyword table for any occurrence of those words, and then output a list of IDs associate with the keyword.
I want to add those ID's to a new array that will also contain a count value and (from a new query) the name of the place belonging to the ID, resulting in:
array(ID, count, name)
For each search word I want to go through this process and if the ID is already in the above array I want to increase the count value and if not, I want to add it with a count value of 1.
When the array is built and all the counting is done, I want to sort it by count and then name, and then output the results.
I've programmed PHP for quite some time but I've never been good with building and manipulating arrays so any help related to building, searching, editing, and sorting a 3-column array is appreciated.
Here's some code below where I'm just trying to insert data into the array and spit it out, which obviously doesn't work:
<?php
$id = 5;
$count = 1;
$name = "PlaceName1";
$arrayPlaces = array($id, $count, $name);
echo "5: " . $arrayPlaces[5] . "<br />";
?>
<?php
$id = 5;
$count = 1;
$name = "PlaceName1";
$arrayPlaces = array(
$id => array(
'count' => $count,
'name' => $name
)
);
echo "5: " . $arrayPlace[5]['name'] . "<br />";
?>
I have an sql query that outputs a lot of information. What I need to do is group and summarize the information in the output table. Here is an example of what i'm trying to do:
name val1 val2 val3 total Run
some name 18 4 1 23
some name 5 4 1 23 2
some name 13 8 2 23 1
other name 2 2 0 4 1
and name 2 42 1 45 1
The name that is coming in from the database can appear more then once. If it does I group those items together and add the Summary row above which would have the same name but also compute the totals:
Val1 has to be added together
Val2, Val3 has to be the same as the row with the largest value in RUN cell
total value always stays the same.
There would be multiple occurrences of such grouping in the output table.
I tried to google my question but the closest that I got to what I was looking for was this this: How to add rows in middle of a table with jQuery?
which is not really what I am doing.
I'm not sure if there is an sql command that I could use to do that, or if it can be done in php or with use of jquery. Any suggestions will be appreciated.
Thank you!
Update:
I have tried using GROUP BY in sql, but it gives me syntax error:
SELECT name, val1, val2, val2, run
FROM tableName
WHERE ... ORDER BY name DESC GROUP BY name
(don't mind the WHERE ... I actually have statements there).
The only time it actually grouped the query when I have two or three results in the query and all of the three have the same name. So I though the GROUP BY is not the option.
In the php I am storing the name into a variable and checking if the name the same or not. if it's not the same i add master class to the row, if not the class is child, which helps me group it. However I didn't figure out a way to add a summary row above.
I was thinking for every time the name changes add a blank row and use jquery to populate it after page is loaded, however, for one time occurances of a name I do not need the summary.
As for, Val3 in the summary row I have made changes above. Val3 will be the same as the val3 in the row with the largest run value. I think I was confused by my own example.
I hope this information is more helpful.
Whenever I have to do something like this, I use multi-dimensional associative array with the top level keys being the highest level of grouping that I want to do. In your case, that would be "name".
In each element of that array, there is another assoc array with a key for each value that I want to keep track of. There is also a numbered sub-array that will contain each individual row that belongs in that grouping.
After I finish going through all the rows, I go through the resulting associative array and print the results.
For example:
<?php
/** Simulate of the results of your SQL query **/
$sql_result = array(
array("name"=>"some name ", "val1"=>5, "val2"=>4, "val3"=>1, "run" =>2),
array("name"=>"some name ", "val1"=>13, "val2"=>8, "val3"=>2, "run" =>1),
array("name"=>"other name", "val1"=>2, "val2"=>2, "val3"=>0, "run" =>1),
array("name"=>"and name", "val1"=>2, "val2"=>42, "val3"=>1, "run" =>1)
);
/** Add each result to your assoc array **/
$names = array();
foreach($sql_result as $row) {
$name = $row["name"];
// Create a new assoc array for each different name
if( !$names[$name] ) {
$names[ $name ] = array(
"name" => $row["name"],
"max_run" => $row["run"],
"val1" => $row["val1"],
"val2" => $row["val2"],
"val3" => $row["val3"],
"runs" => array( $row )
);
continue;
}
// Update the necessary values for the highest "run" number
if ($row["run"] > $names[ $name ]["max_run"]) {
$names[ $name ]["max_run"] = $row["run"];
$names[ $name ]["val2"] = $row["val2"];
$names[ $name ]["val3"] = $row["val3"];
}
// Update the reset of the values
$names[ $name ]["val1"] += $row["val1"];
$names[ $name ]["total"] = $names[ $name ]["val1"] + $names[ $name ]["val2"] + $names[ $name ]["val3"];
$names[ $name ]["runs"][] = $row;
}
/** Print your results **/
foreach ($names as $name) {
// Print your totals here like $name["total"], $name["val1"]
echo $name["name"]." ";
echo $name["val1"]." ";
echo $name["val2"]." ";
echo $name["val3"]." ";
echo $name["total"]."<br>";
if ( count($name["runs"]) > 1 ) {
foreach( $name["runs"] as $run ) {
echo print_r($run)."<br>";
}
}
echo "<hr>";
}
?>
This code is tested
I previously designed the website I'm working on so that I'd just query the database for the information I needed per-page, but after implementing a feature that required every cell from every table on every page (oh boy), I realized for optimization purposes I should combine it into a single large database query and throw each table into an array, thus cutting down on SQL calls.
The problem comes in where I want this array to include skipped IDs (primary key) in the database. I'll try and avoid having missing rows/IDs of course, but I won't be managing this data and I want the system to be smart enough to account for any problems like this.
My method starts off simple enough:
//Run query
$localityResult = mysql_query("SELECT id,name FROM localities");
$localityMax = mysql_fetch_array(mysql_query("SELECT max(id) FROM localities"));
$localityMax = $localityMax[0];
//Assign table to array
for ($i=1;$i<$localityMax+1;$i++)
{
$row = mysql_fetch_assoc($localityResult);
$localityData["id"][$i] = $row["id"];
$localityData["name"][$i] = $row["name"];
}
//Output
for ($i=1;$i<$localityMax+1;$i++)
{
echo $i.". ";
echo $localityData["id"][$i]." - ";
echo $localityData["name"][$i];
echo "<br />\n";
}
Two notes:
Yes, I should probably move that $localityMax check to a PHP loop.
I'm intentionally skipping the first array key.
The problem here is that any missed key in the database isn't accounted for, so it ends up outputting like this (sample table):
1 - Tok
2 - Juneau
3 - Anchorage
4 - Nashville
7 - Chattanooga
8 - Memphis
-
-
I want to write "Error" or NULL or something when the row isn't found, then continue on without interrupting things. I've found I can check if $i is less than $row[$i] to see if the row was skipped, but I'm not sure how to correct it at that point.
I can provide more information or a sample database dump if needed. I've just been stuck on this problem for hours and hours, nothing I've tried is working. I would really appreciate your assistance, and general feedback if I'm making any terrible mistakes. Thank you!
Edit: I've solved it! First, iterate through the array to set a NULL value or "Error" message. Then, in the assignations, set $i to $row["id"] right after the mysql_fetch_assoc() call. The full code looks like this:
//Run query
$localityResult = mysql_query("SELECT id,name FROM localities");
$localityMax = mysql_fetch_array(mysql_query("SELECT max(id) FROM localities"));
$localityMax = $localityMax[0];
//Reset
for ($i=1;$i<$localityMax+1;$i++)
{
$localityData["id"][$i] = NULL;
$localityData["name"][$i] = "Error";
}
//Assign table to array
for ($i=1;$i<$localityMax+1;$i++)
{
$row = mysql_fetch_assoc($localityResult);
$i = $row["id"];
$localityData["id"][$i] = $row["id"];
$localityData["name"][$i] = $row["name"];
}
//Output
for ($i=1;$i<$localityMax+1;$i++)
{
echo $i.". ";
echo $localityData["id"][$i]." - ";
echo $localityData["name"][$i];
echo "<br />\n";
}
Thanks for the help all!
Primary keys must be unique in MySQL, so you would get a maximum of one possible blank ID since MySQL would not allow duplicate data to be inserted.
If you were working with a column that is not a primary or unique key, your query would need to be the only thing that would change:
SELECT id, name FROM localities WHERE id != "";
or
SELECT id, name FROM localities WHERE NOT ISNULL(id);
EDIT: Created a new answer based on clarification from OP.
If you have a numeric sequence that you want to keep unbroken, and there may be missing rows from the database table, you can use the following (simple) code to give you what you need. Using the same method, your $i = ... could actually be set to the first ID in the sequence from the DB if you don't want to start at ID: 1.
$result = mysql_query('SELECT id, name FROM localities ORDER BY id');
$data = array();
while ($row = mysql_fetch_assoc($result)) {
$data[(int) $row['id']] = array(
'id' => $row['id'],
'name' => $row['name'],
);
}
// This saves a query to the database and a second for loop.
end($data); // move the internal pointer to the end of the array
$max = key($data); // fetch the key of the item the internal pointer is set to
for ($i = 1; $i < $max + 1; $i++) {
if (!isset($data[$i])) {
$data[$i] = array(
'id' => NULL,
'name' => 'Erorr: Missing',
);
}
echo "$i. {$data[$id]['id']} - {$data[$id]['name']}<br />\n";
}
After you've gotten your $localityResult, you could put all of the id's in an array, then before you echo $localityDataStuff, check to see
if(in_array($i, $your_locality_id_array)) {
// do your echoing
} else {
// echo your not found message
}
To make $your_locality_id_array:
$locality_id_array = array();
foreach($localityResult as $locality) {
$locality_id_array[] = $locality['id'];
}