I would like to sort data from my database. I want to use associative arrays so it can be sorted the best.
I get all the data from a database, as said above. By doing $row['manufacturer'] I'll get some data like the following:
motorola
sony
motorola
google
samsung
lg
samsung
I would like it to be saved like this in the array: (order is not important, although alphabetically is preferred)
"motorola" => 2
"sony" => 1
"google" => 1
"samsung" => 2
"lg" => 1
I tried it by doing this, but it just didn't work and caused my web host to clean the logs, as it caused almost 2 gigs of log files.
The code I wrote to save it
$manufacturers = array();
//$row are the rows from my database. I will not add them, but by doing $row['manufacturer'] you'll get some brands like google, motorola, etc.
while($row = $resultSelect->fetch_assoc()) {
for ($i = 0; $i < $manufacturers; $i++) {
$alreadyEntered = 0;
if ($manufacturers[$i] == $row['manufacturer']) $alreadyEntered = 1;
if ($alreadyEntered == 0) {
$manufacturers[$row['manufacturer']] = 1;
} else {
$manufacturers[$row['manufacturer']] += 1;
}
//It caused huge logs, so I decided to break on 50.
if ($i > 50) {
break;
}
}
}
//Dump it :) to see if it worked
var_dump($manufacturers);
I have no idea how I can make it work. I tried searching on Google and SO for setting values in associative arrays, but nothing worked.
EDIT:
My rows:
You could do it through SQL query.
Using the count and group by query.
SELECT name, COUNT(*) as total
FROM manufactures
GROUP BY name
ORDER BY name ASC
name is your manufactures name column. manufactures is your table name.
Example PHP code:
$sql="SELECT name, COUNT(*) as total
FROM manufactures
GROUP BY name
ORDER BY name ASC";
$result=mysqli_query($con,$sql);
while($row = mysqli_fetch_assoc($result))
{
echo "Name: ". $row['name'] . " Total: ". $row['total'] . "<br>";
}
Brief explanation:
What the query will do is that it will select all manufactures name, and count them. By in the same time, it will group together the names, which means, multiple same name will be grouped together, and counted together. Finally order by name asc is used to sort the result alphabetically in ascending order (A->Z).
Related
I have a database with multiple users. Each user has an id, name and position. I want to display users by position. To take an example I have a table with 7 numbered positions.
Position Name
1.
2.
3.
4.
5.
6.
7.
And 4 users in the database that I want to display according to their position.
Name Position
User_1 4
User_2 7
User_3 1
User_4 3
How can I do this without using the loop for or while for display?
I tried
for ($j=1; $j<=$no_rows; $j++){
$rand = mysqli_fetch_array($tabel);
$name[$j]=trim($rand['user']);
}
And then display for each number in that table that name[j].
Position Name
1. $name[1]
2. $name[2]
3. $name[3]
4. $name[4]
5. $name[5]
6. $name[6]
7. $name[7]
If those 4 users have positions 1,2,3,4, they are arranged by position, if one has the position higher than the total number of users then nothing is displayed, or it is displayed chaotically.
I also tried with j <= 7 but again the same problem.
The question needs more info but here is a rough idea based on what you have so far and my making some assumptions that this is a leader board style list.
// Something like: $query = 'SELECT * FROM users ORDER BY point DESC';
$count = 1;
while ($row = mysqli_fetch_array($query_results_object))
{
// Process data here.
echo $count . ': ' . $row['username'];
// Bail on 7.
if ($count >= 7)
{
break;
}
$count ++;
}
// Fill in empty values.
while ($count < 7)
{
echo $count . ': Space available.';
}
You did say without using the loop for display and your modified example appears to indicate you want rank instead of leader board position.
// Something like: $query = 'SELECT * FROM users';
$list = array_fill(1, 7, 'empty_value');
while ($row = mysqli_fetch_array($query_results_object))
{
// Process data here.
$list[$row['rank']] = $row['name'];
}
echo $list[1];
echo $list[2]];
...
This would be very inefficient as if you had 100 users you would be adding all of them to an in-memory table only to display 7 of them. So make sure you query does something like: SELECT TOP 7 * FROM users ORDER BY position DESC
How can I find the position a certain row has in my database table?
In my database I have a bunch of Players from a game. They have columns such as ID, name, level, world, and so on.
I want to sort them by Level, and see what position they are in in the list.
So far I've tried this, but it only prints out 0 (the start value I put). It does not seem to iterate through.
Previously I made sure the name is stored in $name.
$query = "SELECT * FROM rookstayers ORDER BY level DESC";
$globalPos = 0;
$result = mysql_query($query);
$num = mysql_numrows($result);
$i = 0;
while($i < $num) {
$posName = mysql_result($result, $i, 'name');
if($posName == '$name')
{
$globalPos = $i;
break;
}
$i++;
}
If my table looks like this (after sorting it by level):
name - level
Joe - 50
Jacob - 47
Sarah - 34
Anna - 19
Then "Sarah" would be number 3.
Anna number 4, etc...
I want the position-number to be in $globalPos.
I only found pure SQL code for this, but I want it in PHP. Is it not possible to do in PHP?
I'm not sure if this is the only problem:
If you use single quotes ', the string is not parsed for variables. If you want to compare a string stored in $name with a string stored in $posName, you should use $posName === $name. You could also use $posName === "$name", but the double quotes are unnecessary.
Notice also, that the mysql functions are deprecated. You should use mysqli or PDO_MySQL instead. (See Choosing an API)
<?php
/*
CREATE TABLE results
(name VARCHAR(12) NOT NULL PRIMARY KEY
,score INT NOT NULL
);
INSERT INTO results VALUES
('Anna',19),
('Jacob',47),
('Joe',50),
('Sarah',34);
*/
include('path/to/connection/stateme.nts');
$query = "
SELECT name, score FROM results ORDER BY score DESC;
";
$result = mysqli_query($conn,$query);
$i=1;
while($row = mysqli_fetch_assoc($result)){
echo $i." ".$row['name']." ".$row['score']."<br/>\n";
$i++;
};
?>
I am trying to pull a list of genres from the database. I enter a list of genres into the database for each song, and then it (is supposed to) pull each song's genre into a list and order them by the top three most common occurrences.
The genres get put into a single text field in such a fashion:
(basic fashion, not an actual result):
blues rock, garage rock, hard rock
Here's my code:
$sql = "SELECT `song_name`, `song_genres` FROM `songs` WHERE `album_id` = '$songAlbumId'";
$query = mysqli_query($conn, $sql);
while ($row = mysqli_fetch_array($query)){
$song_name = $row['song_name'];
$song_genres = explode(", ", $row['song_genres']);
for ($i = 0; $i < count($song_genres); $i++){
$count=array_count_values($song_genres);//Counts the values in the array, returns associatve array
arsort($count);//Sort it from highest to lowest
$keys=array_keys($count);//Split the array so we can find the most occuring key
echo $keys[$i] . "<br>";
}
}
This ends up giving me:
Hard Rock
Garage Rock
Hard Rock
Garage Rock
Psychedelic Rock
Blues Rock
Garage Rock
Hard Rock
Also note there is nothing wrong with the album id or anything else. It is specifically to do with just the genres being ordered right.
Normalize the genres. Use a genres table instead of a comma separated list, and an additional songs_genres table to link songs to genres. Then you can get the data from the database without further logic in php
SELECT g.name, COUNT(DISTINCT(sg.song_id)) cnt
FROM genres g
INNER JOIN songs_genres sg ON sg.genre_id = g.id
GROUP BY g.name
ORDER BY cnt DESC
LIMIT 3
You need another loop so your genres echo for each songname
while ($row = mysqli_fetch_array($query)){
$song_name = $row['song_name'];
$song_genres = explode(", ", $row['song_genres']);
foreach($song_name as $songname){
for ($i = 0; $i < count($song_genres); $i++){
$count=array_count_values($song_genres);//Counts the values in the array, returns associatve array
arsort($count);//Sort it from highest to lowest
$keys=array_keys($count);//Split the array so we can find the most occuring key
echo $keys[$i] . "<br>";
}
}
}
I spent a couple days trying to figure it out. I ended up reworking the database and posting the songs genres into a database for the song, album, and band sections to easily pull from.
For anyone in the future who wants help with a problem like this, the solution is here: Merge multiple arrays into one array.
I appreciate the input from the other people though.
i need help displaying this in two different lists
$domains_sql = mysql_query("SELECT domains_id, domains_url, keywords_id, keywords_word, domains_comments_comment
FROM
(
SELECT domains_id,domains_url
FROM domains
ORDER BY RAND()
LIMIT 1
) as d
INNER JOIN domains_comments
ON domains_comments_domain = domains_id
INNER JOIN domains_keywords
ON domains_keywords_website = domains_id
INNER JOIN keywords
ON domains_keywords_keyword = keywords_id
ORDER BY keywords_word ASC") or die (mysql_error());
$num = mysql_num_rows($domains_sql);
$current_price = "";
for($i=0;$i<$num;$i++){
$domains_result = mysql_fetch_array($domains_sql);
$domains_id = $domains_result['domains_id'];
$domains_url = $domains_result['domains_url'];
$domains_name = preg_replace('#^https?://www.#', '', $domains_url);
$keywords_id = $domains_result['keywords_id'];
$keywords_word = $domains_result['keywords_word'];
$domains_comments = $domains_result['domains_comments_comment'];
if($domains_url != $current_price) {
echo $domains_name."<br /><br />";
$current_price = $domains_url;
}
echo $keywords_word."<br />";
echo $domains_comments."<br />";
}
prints out:
MS Office
domain 1
MS Office
domain 1 - part 1
MySQL
domain 1
MySQL
domain 1 - part 1
PHP
domain 1
PHP
domain 1 - part 1
Visual Basic
domain 1
Visual Basic
domain 1 - part
and i need it to be:
(info from keywords)
MS Office
MySQL
PHP
Visual Basic
(info from comments)
domain 1
domain 1 - part 1
I'm not sure if I see how your domain comments and keywords are related, and if you simply want two lists or if you want one comment-list per keyword.
Anyway, you could rewrite your query logic to make a primary query for the keywords, and then run simpler queries for the comments (either one for all, or one per keyword), but if your query time and dataset is such that you prefer doing it in a single query you can restructure the data in multiple-leve arrays.
Also, i presume you only want to list every item once.
$keywords = array();
$comments = array(); //if you want all comments in one list
for($i=0;$i<$num;$i++){
$domains_result = mysql_fetch_array($domains_sql);
//Stores complete row data, only keeps the last, if the same value is fetched from the db several times
$keywords [$domains_result['keywords_word']] = $domains_result;
$comments[$domains_result['domains_comments_comment']] = $domains_result;
}
//Now you have the two list, could be printed several ways, to only print the values
print implode("<br />\n",array_keys($keywords));
print "<br />";
print implode("<br />\n",array_keys($comments));
//Loop trough
foreach ($keywords as $keyword=>$data) {
print "$keyword<br>\n";
print $data['keywords_word']."<br>\n";
print_r($data);
}
I'm coding in PHP/MySQL and have the following query to fetch products and product group data:
SELECT products.id,products.name,product_groups.id,product_groups.name
FROM products
INNER JOIN product_groups
ON products.id=product_groups.id
WHERE products.name LIKE '%foobar%'
ORDER by product_groups.id ASC
So this query fetches products and orders them by product group. What I would like to have is to display product_groups.name just once for each product grouping. So even if I have ten shoe products, the group name "Shoes" is only displayed once.
I'm using the following PHP to print out the results:
while ($data = mysql_fetch_array($result))
If you want it done in the MySQL query, it is honestly more trouble than it's worth. For one, the syntax is really wonky (as I recall) to have a group name listed at the top of each grouping. And the results are still treated as rows, so the group name will be treated like a row with all the other columns as Null, so you won't really save any time or effort in the PHP script as it has to do an if statement to catch when it hits a group name instead of the group data.
If you want it done by the PHP while loop, Johan is on the right track. I use the following for a similar situation:
$result = $sql->query($query);
$prev_group = "";
while($data = $result->fetch_assoc()){
$curr_group = $data['group'];
if ($curr_group !== $prev_group) {
echo "<h1>$curr_group</h1>";
$prev_group = $curr_group;
}
else {
echo $data;
.....
}
Obviously the echo data would be set up to echo the parts of the data the way you want. But the $prev_group/$curr_group is set up so that the only time they won't match is when you are on a new group and thus want to print a header of some sort.
while($data = mysql_fetch_assoc($result)){
if($data['product_groups.name'] != $groupname){
echo "Groupname: ".$data['product_groups.name']."<br />";
$groupname = $data['product_groups.name'];
}
echo "ID: ".$data['products.id']."<br />";
echo "Name: ".$data['products.name']."<br />";
}
Maybe you can do like this!?