PHP Multi Dimensional Array Sorting - php

Edit : I need it to do only in Array Sort, As i am using procedure and sending it into json,
Here is my Table Structure,
SQL Fiddle
I want to display as
alpha london
alpha newyork
beta delhi
beta sydney
I mean, the second coloumn (name) should be in Ascending Order and the third coloumn (place) should be in Descending Order.
How i want is
alpha london
alpha newyowk
beta delhi
beta sydney
The Name should be in Asc Order and then to the right, the Place should be in Desc Order
What i have tried so far is
How can i do this ??
<?php
include ('conn.php');
$sql="SELECT * FROM test";
$result=mysql_query($sql);
$rows=mysql_fetch_array($result);
while($rows=mysql_fetch_array($result))
{
foreach($result as $k=>$v)
{
echo $k;
}
}
?>
It displays the result as Invalid argument supplied to for each. What is the mistake i am doing and how can achieve my output

To fix the sorting, just add ORDER BY name, place
Then there's several more issues preventing this from working:
You shouldn't call mysql_fetch_array outside the loop (this would discard the first row, alpha london in your example).
You need to iterate over $rows, not $result (this is where the "invalid argument" error is coming from).
You're not echoing the value; only the key. So you wouldn't be displaying the name and place at all; only the words "name" and "place".
You might want to do something like this to fix these:
<?php
include('conn.php');
$sql = "SELECT * FROM test ORDER BY name, place";
$result = mysql_query($sql);
while ($rows = mysql_fetch_array($result)) {
foreach ($rows as $k => $v) {
echo "$k is $v. ";
}
echo "<br/>";
}
?>

So why don't you do an order in your query itself like
SELECT * FROM test order by name;

You can do this only modifying query.
Use this query:
SELECT * FROM test ORDER BY name ASC, place DESC

For your error, you are using wrong variable as foreach.
Replace this -
foreach($result as $k=>$v)
{
echo $k;
}
with this -
foreach($rows as $k=>$v)
{
echo $k;
}
Buy why are using foreach inside while loop. You can get your values like -
while($rows = mysql_fetch_array($result)) {
echo $rows['name'].' '.$rows['place'].'<br/>';
}
and don't use mysql_* function. Use instead mysqli_*
And for your expected output, try using following query -
SELECT * FROM `test` order by name asc, place desc

This is the kind of thing you can fix using array_multisort.
Try the below example (which I have not tested yet, but ought to work)
<?php
include ('conn.php');
$sql="SELECT * FROM test";
$result=mysql_query($sql);
$totals = array();
$row = array();
$places = array();
while($row=mysql_fetch_array($result)){
$totals[] = $row
$names[] = $row['name'];
$places[] = $row['place'];
}
array_multisort( $names, SORT_ASC, $places, SORT_DESC, $totals );
// now you can use $totals, which is sorted as you want
print_r( $totals );

Related

echo in reverse order from mysql_fetch_assoc()

Ok here's the trick.
In the query I'm getting the right results from a table named messages. (Its fetching the last 10 messages ordered by the time inserted in reversed order) here's the query:
$query = mysql_query("SELECT time, username, message
FROM messages ORDER BY time DESC LIMIT 10");
And than later those messages are printed inside div via ajax with
while ($item = mysql_fetch_assoc($query)) {
echo $item['time']." - ".$item['username']." - ".$item['message'];
}
But the printed result I want to print them only in the reversed order.
Tip: If I use ASC in the ORDER BY clause I don't get the last inserted messages.
Is this possible to do inside php?
Store your data & than use array_reverse,
while($row = mysql_fetch_assoc($result)){
$items[] = $row;
}
$items = array_reverse($items ,true);
foreach($items as $item){
echo $item['time']." - ".$item['username']." - ".$item['message'];
}
I would use a subquery personally. Im kinda anal about having my data come out of MySQL exactly how I want it, but the array_reverse method will work fine too. Here is my example:
$query = mysql_query("SELECT * FROM (
SELECT time, username, message
FROM messages ORDER BY time
DESC LIMIT 10) result
ORDER BY time ASC
");
Use: array_unshift - Prepend one or more elements to the beginning of an array
$items = array();
while($row = mysql_fetch_assoc($result)){
array_unshift($items,$row);
}
foreach($items as $item){
echo $item['time']." - ".$item['username']." - ".$item['message'];
}
Heres a useless but quick example. I hope it's still there: Simple example

Order after executed?

Im trying to do a PHP script where it order users based on a point system. Problem is that the points is calculated after I execute the users. Like this:
$getScore = $db->prepare("SELECT * FROM `users`");
$getScore->execute();
$results = $getScore->fetchAll();
foreach($results as $row):
$likes = $get->likes("user", $row["id"]);
$subscribers = $get->subscribers("user", $row["id"]);
$score = $get->score($likes, $subscribers, $row["date"]);
echo $row["username"];
endforeach;
Without having another execution how do I order the results? I want the user with highest value on $score to be shown first. I've tried alot of things but without succession.
Thanks in advance!
You can implement this different ways.
If you have already loaded all the data from the databse you can order them using PHP.
Custom sorting can be done using usort.
PHP.net - usort documentation
Maybe you could use something like this:
$users = array();
// Load all the users and calculate scores
foreach($results as $row):
$users[$row["username"]] = $get->score($likes, $subscribers, $row["date"]);
endforeach;
// Sort users based on score
sort($users);
// Output users, sorted by score
foreach($score as $key => $row):
echo $key, " score:", $score;
endforeach;
If you would like to use a more complex data structure, all you have to do is implement the special comparision to ensure ordering by score with usort.
If you store the points in the database, then you could use a special query including an ORDER BY clause, this way returning the users already ordered.
I think using the DBMS to order the users would result in a more scalable solution. If you have really high number of users, it is not going to perform well to sort all the users each page load.
First, sorry for suggesting another execution flow. Next, this is my solution:
$getScore = $db->prepare("SELECT * FROM `users`;");
$getScore->execute();
$results = $getScore->fetchAll();
// Result is something like [rownum][colomname]
array_walk_recursive($results, function($item, $key) {
$id = $item["id"];
$date = $item["date"];
$arr = array();
$arr['likes'] = $get->likes("user", $id);
$arr['subscribers'] = $get->subscribers("user", $id);
$arr["score"] = $get->score($arr["likes"],
$arr["subscribers"],
$date);
$item = array_merge($item, $arr);
});
In this code you get the results from your database. Next you calculate things like the score and you add this to the array.
To sort this array on the score you can use the PHP multisort function (http://php.net/manual/en/function.array-multisort.php):
foreach ($results as $key => $row) {
$score[$key] = $row["score"];
}
array_multisort($score, SORT_DESC, $results);
When you're looping your loop to print the data for example you can do this:
foreach($results as $row) {
$likes = $row["likes"];
$subscribers = $row["subscribers"];
$score = $row["score"];
echo("your stuff over here");
}
Good luck!

Live sort query results in php

I have a query which goes through the table and outputs the data like this:
Query
$query = mysql_query("SELECT * FROM `products`");
while($row = mysql_fetch_assoc($query)){
$array[] = $row;
}
foreach ($array as $key) {
$name[] = $key['name'];
$desc[] = $key['desc'];
$cost[] = $key['price'];
}
$c = 0;
while($c<(count($array))){
echo 'Name: '.$name[$c].'<br>';
echo 'Desc: '.$desc[$c].'<br>';
echo 'Price: '.$cost[$c].'<br><br>';
$c++;
}
Results
Name: xyz1
Desc: asdxsadasda
Price: 999
Name: xyz2
Desc: asdxsadasda
Price: 333
Name: xyz3
Desc: asdxsadasda
Price: 666
I want to be able to sort these results based on the price of each item.
Can I output the result in a jSON file and use that to sort the results (live-without loading the page)?
Could you suggest me a better way to sort the results without having to load the page?
If you MUST sort the array in PHP, after you got the query result, use the array_multisort function in PHP (http://www.php.net/manual/en/function.array-multisort.php)
However, if your life does not depend on sorting in PHP, sort at the source in your SQL (the way God intended it to be) it's going to be much much faster and it will take the load off the web server.
Hope this helps.
$query = mysql_query("SELECT * FROM `products` WHERE `category` order by products.price, products.name");
You choose sort by ASC or DESC
SELECT * FROM `products` order by price, name
Also, your foreach is not needed as you can do your array setup in the while loop.

PHP Nested Loop. How on the second loop print items according to the id of the first loop?

I need to print a wine list from a database.
I need to print at first a categorie and after all the items that are inside. Thats the order. And i have multiple categorie. So at the end the result will be categorie1, many items, categorie2 many items...
This is the code that i write from now: I think that my problem is to print items according to the id of the alcool_categorie !!
$q_vine = "SELECT * FROM alcool_categorie ";
$r_vine = mysql_query($q_vine,$connection);
$n_vine = mysql_num_rows($r_vine);
$q_bouteille = "SELECT * FROM alcool_item where ALCNID = '$alid'";
$r_bouteille = mysql_query($q_bouteille,$connection);
$n_bouteille = mysql_num_rows($r_bouteille);
for($i = 0; $i < $n_vine; $i++){
echo mysql_result($r_vine,$i,'named').'<br/><br/>';
for($z = 0; $k < $n_bouteille; $k++){
echo mysql_result($r_bouteille,$k,'name').'<br/>';
}
}
I think it's best to use a "JOIN" in your query and then order the rows in the way you want them to be ordered, then you'll only need one loop. While running the loop you compare the category name with the previous category name and if it changes display the category name.
Example
$sql = "SELECT categoryName, bottleName FROM category INNER JOIN bottle ON category.categoryId = bottle.categoryId ORDER BY category.categoryId";
$result = mysql_query($sql,$connection);
$categoryName = ''; //just to make sure the first time the Category is named
while ($row = mysql_fetch_assoc($result)) {
if($categoryName != row['categoryName']){
$categoryName = row['categoryName'];
echo '<h1>'.$categoryName.'</h1>';
}
echo row['bottleName'].'<br/>';
}
Try this after correctly giving the category id field name in the query and inside the first while loop.
$q_vine = "SELECT id, named FROM alcool_categorie ";
$r_vine = mysql_query($q_vine,$connection);
$n_vine = mysql_num_rows($r_vine);
while ($row = mysql_fetch_assoc($r_vine)) {
$categories[$row['id']] = $row;
}
$q_bouteille = "SELECT name, ALCNID FROM alcool_item ";
$r_bouteille = mysql_query($q_bouteille,$connection);
$n_bouteille = mysql_num_rows($r_bouteille);
while ($row = mysql_fetch_assoc($r_bouteille)) {
$items[$row['ALCNID']] = $row;
}
foreach ($categories as $category_id=>$category) {
echo "<ul><li>{$category['named']}<ul>";
foreach ($items[$category_id] as $item) {
echo "<li>{$item['name']}</li>";
}
echo "</ul></li></ul>";
}
You will want to look into PHP's foreach construct. Foreach loops through an entire array of results, for each element inside the array, it extracts its value and optionally also its key. This will not require the use of mysql_num_rows.
Instead of calling mysql_result, you could use mysql_fetch_assoc to get a row's value from your mysql_query. The row's To get all values, you can incorporate this into a loop even. If you do the latter, you can create your own array of key/value pairs and use this inside a foreach construct.
Also note that the use of mysql is outdated, you will want to use mysqli now, which is very similar to mysql.

How to sum result of query

I have one query where the output processing looks like this:
while($row = mysql_fetch_array($result)){
echo $row['username'] . " " . $row['earning'];
}
And outputs result is like this:
JOHN 200
JOHN 350
NEO 100
NEO 220
What I want to achieve is that every name appears once, and "earning" is sum of all earnings of that name, like this:
JOHN 550
NEO 320
I have to mention that I CANNOT change the query; that is biggest problem.
Is there any hope? Some suggestions? :)
You can sum the values in the loop to another array and then output it.
Try:
$earnings = array();
while($row = mysql_fetch_array($result)) {
if (!isset($earnings[$row['username']])) $earnings[$row['username']] = 0;
$earnings[$row['username']] += $row['earning'];
}
foreach($earnings as $user => $earnings) {
echo "$user $earnings<br />\n";
}
try:
$user = array();
while($row = mysql_fetch_array($result)){
$user[$row['username']] += $row['earning'];
}
to do echo :
foreach($user as $key => $value) {
echo $key."=". $earnings."<br>";
}
To get a quick solution to this answer you may want to simply append these results to an associated array and then simply loop over it to get the final count.
So, something like this:
$names= array();
while($row = mysql_fetch_array($result)){
$names[$row["username"]] += $row["earning"];
}
foreach($names as $k => $v) {
echo $k." ".$v."\n";
}
Instead of just selecting the data, select the field and SUM(otherfield) with otherfield being the field with the number to be summed. Then add GROUP BY with the first field.
try this in mysql side you don't need to calculate in php side so don't change your PHP side code jst change query like this
SELECT
username,
SUM(earning)
FROM yourtable
GROUP BY (username)
hope its will work for you

Categories