php mysql while - loop while condition is the same - php

I have a db that have this kind of structure:
name|color
paul|blue
mary|red
paul|green
joe |yellow
paul|purple
mary|orange
paul|white
etc |etc
What am I trying to achieve here is to list the colors associated with a name, something like this:
paul=blue,green,purple,white
mary=red,orange
joe=yellow
I was checking some examples and found this:
$query="SELECT * FROM mytable order by name";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
echo $row['name']. " - ". $row['color'];
echo "<br />";
}
To be honest I just don't know how to go from this to what an I trying to achieve. How can I create a condition that will list all the color associated with one name and then jump to the next and so on?

You need to use GROUP_CONCAT. Try something like this:
SELECT
name,
GROUP_CONCAT(color) AS color
FROM mytable
GROUP BY name
See this fiddle - updated
If you need to account for duplicates, use GROUP_CONCAT(DISTINCT color). You can also include a custom SEPARATOR, but if you leave it out the default is ,. So in your case you don't need to specify. Also, as can be seen in the documentation linked above, you can, if desired, order the colors in whichever way you see fit - although, note that the default order is ASC, so you don't need to specify that, either, unless you want to change it.

You can do all with the SQL query:
SELECT name, GROUP_CONCAT(DISTINCT color ORDER BY color DESC SEPARATOR ',')
FROM mytable
GROUP BY name;

thank you for pointing me into the right direction. I manage to gather more info and make it work with this:
$query="SELECT name, GROUP_CONCAT(color) FROM mytable GROUP BY name";
$result = mysql_query($query) or die(mysql_error());
while($row=mysql_fetch_array($result))
{
echo "<tr>";
echo "<td>" . $row['name'] . "</td>";
echo "<td>" . $row['GROUP_CONCAT(color)'] . "</td>";
echo "</tr>";
}
Thank you again :)

Related

How do I organize all the rows that contain the same FK ID into one row that shows all the items inside those rows

I am trying to make all the data I have in my database organized by SaleID, this is how I have my DB right now. SalesID and ProductID are foreign keys.
TID.......SaleID .........ProductID
....1...............1.......................1
....2...............1.......................4
....3...............1.......................6
....4...............2.......................3
....5...............3.......................1
....6...............3.......................5
....7...............4.......................3
....8...............5.......................3
....9...............5.......................6
I want to make a table that shows all the data organized like this. Not stored into a database just to output this information.
SaleID........Products
.........1.......1,4,6
.........2.......3
.........3.......1,5
.........4.......3
.........5.......3,6
I was trying to do this with multidimensional arrays but every iteration it added a new row and showed exactly the same thing as the first table not being able to modify or add to a past row.
this is the code that I have right now
<?php
mysql_connect('localhost','root','');
mysql_select_db('mydb');
$query="SELECT * FROM prodsales ORDER by salesID ASC";
$result = mysql_query($query);
echo "<table border='1'>";
while($row = mysql_fetch_array($result)){
echo "<tr><td>" . $row['salesID'] . "</td><td>" . $row['productID'] . "</td></tr>";
}
echo "</table>";
mysql_close();
?>
SELECT SaleID , GROUP_CONCAT( DISTINCT ProductID SEPARATOR ',' ) AS PID FROM prodsales GROUP BY SaleID
Please try this hope it help you to get what you wnat
MySQL has a lovely group_concat function as Abhik posted in a comment. You can use it like this to get the distinct rows you want and to make the other matching rows a comma (or just about anything else) separated list:
select
saleID,
group_concat(productID)
from
prodsales
group by
saleID
order by
saleID
This will return the rows in the format you want and you can simply then output into the table as you are doing.

blank spaces and repetition in dropdown box

My drop down boxes are working fine using multiples of this code which, I admit, is very rudimentary:
$sql = "SELECT Country FROM engravers order by Country";
$result = mysql_query($sql);
echo "<select name\\='Country'>";
echo "<option value='$_POST'>Country</option>";
while ($row = mysql_fetch_array($result)) {
echo "<option value='" . $row['Country'] . "'>" . $row['Country'] . "</option>";
}
echo "</select>";
The only problem is that if I have more than one item in the field I get a response for each item, for instance, in my testing database there are two rows with Australia as the country. My dropdown then puts Australia in twice. Later, when there will be about a hundred Australian entries this will be a problem.
Also if there is a blank field I get a blank line in the drop down box. I don't seem to be able to find a solution to this. Is there a better way to write the drop down code that doesn't do this. Unfortunately, as a novice, I am using the simplest code I can understand but the results look just like that. Any help would be gratefully accepted.
Try this query:
SELECT DISTINCT Country
FROM engravers
WHERE Country <> ''
ORDER BY Country
SELECT DISTINCT will take care of multiples - if there are 100 rows with Country = Australia, it will only select one.
WHERE Country <> '' will exclude any rows that have a blank value for Country. You could also include AND Country IS NOT NULL to exclude NULL values as well.
References:
<> (Not equal operator), SELECT DISTINCT ...

MYSQL union PHP select into one result column

Ok, there comes a point where staring at SQL is the only option when Googling has you cross eyed. I can't quite get my head around this. What I'm trying to do, is simply use 1 query to search multiple tables at once and return what it finds. I think I need to just do separate queries for this, but wanted to see if there is a better way.
So, for example, there is a categories table, and a users table. If the user searches for "jo", it might find "jobs" in the categories table, but it should also find "joe" in the users table. These are displayed in a <ul><li> html style with fixed lengths. Is there a way with one query? Ideally if "jobs" is found in the category table, that would end the record and the next record would contain "joe" from the users table (provided that the "jo" didn't have multiple categories from the category table.
I've played around with UNION SELECT, but am not sure if it can perform in this fashion or not. I might be able to get a result back from the query, but since the tables have more than 1 field name that is being searched on, I need to be able to return the result based on where it's from.
For example, something like:
SELECT cat_name as result FROM categories WHERE cat_name LIKE '%$name%'
UNION (SELECT firstname as result, lastname as result, username as result WHERE
firstname LIKE '%$name%' OR lastname LIKE '%$name%' OR username LIKE '%$name%' LIMIT 10
<?php echo $row['result']; ?>
Do you think it needs multiple queries?
I don't see that there is any harm in using multiple queries and using echo to display the results separately as to not confuse (so you know where to results are coming from).
Something like this wont burden your script in anyway and makes it easier to read.
<?php
$con=mysqli_connect("example.com","peter","abc123","my_db");
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$sql = "SELECT cat_name FROM categories WHERE cat_name LIKE '%$name%';";
$result = mysqli_query($con,$sql);
echo "<h1>Category Matches</h1>"
echo "<ul>";
while($row = mysqli_fetch_array($result)) {
echo "<li>" . $row['cat_name'] . "</li>";
}
echo "</ul>";
$sql2 = "SELECT * FROM users WHERE first_name LIKE '%$name%';";
$result2 = mysqli_query($con,$sql);
echo "<h1>User Matches</h1>"
echo "<ul>";
while($row = mysqli_fetch_array($result2)) {
echo "<li>" . $row['first_name'] . "</li>";
}
echo "</ul>";
mysqli_close($con);
?>

Trying to search one table using the value from another table

I am trying to program a lookup tool in PHP with SQL database.
$sql="SELECT
ID,
switch,
vlan,
circuit_id
FROM vlan
WHERE switch
LIKE LOWER('%" . $name . "%') OR vlan='" . $name ."'
ORDER BY vlan";
then further down I have this to put the results into variables:
while($row=mysql_fetch_array($result)){
$switch =$row['switch'];
$vlan=$row['vlan'];
$circuitID=$row['circuit_id'];
$ID=$row['ID'];
What I am wanting to do is take the switch reply and use that to do another query on a different table named router and return that information.
I have been searching for a few days and all of my searches ended up here but didnt seem to quite fit. I apreciate any help you can give.
UPDATE
With some great answers I finally got this to work. Here is how I did it. Thanks for the help.
while($row=mysql_fetch_assoc($result)){
$switch =$row['switch'];
$vlan=$row['vlan'];
$circuitID=$row['circuit_id'];
$ID=$row['ID'];
$sql2 = "SELECT IPAddress FROM router
WHERE switch LIKE '%".$switch."%'
LIMIT 1";
$result2 = mysql_query($sql2);
$row2=mysql_fetch_array($result2);
$IPAddress = $row2['IPAddress'];
Probably real ugly to the more experienced but it works. Thanks again.
It would be highly inefficient to run a secondary lookup query in a loop.
What you want is a simple JOIN between your two tables based on the switch field. What this will do is bring the linked rows in your router table alongside the rows in your vlan table where values in the switch column match up:
$sql = '
SELECT a.id, a.switch, a.vlan, a.circuit_id, b.ipaddress
FROM vlan a
JOIN router b ON a.switch = b.switch
WHERE a.switch LIKE "%' . strtolower($name) . '%" OR vlan = "' . $name . '"
ORDER BY a.vlan';
Then in your same fetch loop, you'll be able to access the linked values from your router table without having to run extra database calls:
while($row=mysql_fetch_array($result)){
$switch =$row['switch'];
$vlan=$row['vlan'];
$circuitID=$row['circuit_id'];
$ID=$row['ID'];
$ipaddress = $row['ipaddress'];
}
How many results do you expect? If there's more than one result, you might need to point which row exactly you want to take. Since it's fetch_array, your $row['switch'] or $switch value is still an array. var_dump it for keys and use the key, i.e.
SELECT `col` FROM `router` WHERE `switch` = '$switch[1]'

Displaying info from MySQL - from 2 different tables... Argh! Noob in trouble

I am trying to pull some stats from a gameserver database, and return them in a table.
I have managed to do the first bit - pulling 10 results, displaying in a table in html, HOWEVER... the next bit has me stumped... I for each player I want to get some info from another table...
Here is what I have so far... excuse the messy code, I am just learning!
// adding ALL info from the first 10 tables 'profile' based on humanity, ascending, to the variable 'profile_info'
$profile_info = mysql_query("SELECT * FROM profile ORDER BY humanity desc LIMIT 10");
while($row = mysql_fetch_array($profile_info))
{
// Below I add the players unique ID into the variable $unique, to be used later for pulling their survival time from the 2nd table, which is called 'survivor'
$unique = $row['unique_id'];
echo "<tr>";
echo "<td class=\"c1\">" . $row['name'] . "</td>";
echo "<td class=\"c2\">" . $row['humanity'] . "</td>";
echo "<td class=\"c3\">" . $row['total_survivor_kills'] . "</td>";
echo "<td class=\"c4\">" . $row['total_bandit_kills'] . "</td>";
echo "<td class=\"c5\">" . $row['total_zombie_kills'] . "</td>";
echo "<td class=\"c6\">" . $unique . "</td>";
//In the line below, I try to get data from the 2nd table (called survivor), checking for the unique_id for the player (extracted from the first table, called 'profile') which is common across both tables and which have a 0 in the field 'is_dead'
$result = mysql_query("SELECT * FROM `survivor` WHERE `unique_id` ='.$unique' AND `is_dead` = 0") or die(mysql_error());
echo $unique;
if (mysql_num_rows($result)) {
$survivors_survival_time = mysql_fetch_assoc($result);
echo "<td class=\"c7\">" . $survivors_survival_time['survival_time'] . "</td>";
}
I hope that, even though the code above is probably rubbish, you can see what I am trying to do?
Most of it works fine, it is just that the part where I try to get the info for a player from the second table, based on their unique_id from their row in the first table, it doesn't work :(
Any ideas, or is the above so bad I should just give up?
I believe you have a typo in your query that pulls info for each individual player here:
mysql_query("SELECT * FROM `survivor` WHERE `unique_id` ='.$unique' AND `is_dead` = 0")
Specifically, the unique_id = '.$unique' part, where there is an extra . in the value field.
Try removing it to get the following:
$result = mysql_query("SELECT * FROM `survivor` WHERE `unique_id`='$unique' AND `is_dead` = 0") or die(mysql_error());
This, of course, is under the assumption that you don't prepend a . to each of your unique_id values in the survivor table.
Side-note (not answer specific):
If you were to update your code to use the MySQLi or PDO libraries opposed to the deprecated mysql_ functions, you would have the ability to use prepared statements. Using these would prevent minor errors like the one noted above as well as provide more-secure code too.
Nest your while loops or read about mysql LEFT JOIN and update your query.
I do not know about MySQL, because I've always used MSSQL, but here's how I would write it in PHP and mssql:
'SELECT * FROM survivor WHERE unique_id="'.$unique.'" AND is_dead = 0'
Try it and let me know ;)
You can combine those queries using a join:
SELECT
*
FROM
profile AS p
LEFT JOIN
survivor AS s ON p.unique_id = s.unique_id
WHERE
s.is_dead = 0
ORDER BY
humanity DESC
LIMIT
10
Then simply loop the results. Using LEFT JOIN gives you all the results from profile and any matches in survivor. If you change that to JOIN (i.e. drop the LEFT) it will give you only rows where a match exists in profile AND survivor.
A couple of suggestions:
Explicitly state which columns you want, i.e. "SELECT name, humanity, survival_time, etc..." instead of SELECT *.
Use a query method that allows you to use prepared statements, such as PDO.
Use single quotes instead of doubles so that you don't have to escape all the doubles in your HTML output. Anyone else who reads your code will thank you for that!

Categories