MYSQL union PHP select into one result column - php

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);
?>

Related

How can I select all id's from a sql table in descending order and then echo them (in php)?

I have several id's in a table called "leaderboards" that belong to different users. They're named as:"id_user" and they're not in order. What I want to do is printing divs in a leaderbord which should contain some info that I get from those id_user's.
The only problem I have about it is that after a research on stackoverflow and other websites, I still couldn't find how to select those id_user's in descending order AND be able to take one by one to get the info from that user and then continue with the next id_user, and so on.
I don't know how to select the specific row of each id_user in descending order to do the other codes that I already know how to do.
I hope it's not a duplicate of any other previosly asked question on this website (I really did a research and I couldn't find any specific answer to this question, for the sql part and the php part all together).
Thank you so so much beforehand.
An INNER JOIN between your tables will achieve what you intend.
SELECT *
FROM users
JOIN leaderboards WHERE users.id = leaderboards.id_user
ORDER BY users.id DESC
In each returned row, you will get the columns from both your users and leaderboards tables, so loop over the result and echo the information from the user you need.
$query = 'SELECT...';
$res = mysqli_query($query);
while ($row = mysqli_fetch_assoc($res)) {
echo '<div>'.$row['id'].' - '.$row['username'].' - '.$row['image'].'</div>';
}
You could do with a good read up on both PHP and MySql but I'll give you a clue.
EDIT
$query = "SELECT * FROM `the_name_of_your_table` ORDER BY `user_id` DESC;";
if ($result = mysqli_query($link, $query)) {
/* fetch associative array */
while ($row = mysqli_fetch_assoc($result)) {
print $row["user_id"] . " - " . $row["username"] . "<BR>";
}
/* free result set */
mysqli_free_result($result);
}

Searching multiple MySQL tables from an HTML form and returning the data in alphabetical order

I'd like to search 3 separate tables I've created from 1 form and return the data in alphabetical order. Currently I can search 3 tables separately with use of a drop-down box (from my form) to select a table but I've fallen short at querying them simultaneously and returning all the data in alphabetical order. I've been trying to solve it but I'm struggling a lot.
Currently what my program searches through separate tables for what the user previously input into my form. Now I would like to be able to search through all my tables in 1 go and return the information in alphabetical order, meaning some values from tables might be spread out.
I have 3 tables: "Insecttable", "birdtable" and "butterflytable"
There are 3 controllers: "ControllerInsectTable", ControllerBirdTable and "ControllerButterflyTable"
I'm trying to make another controller: "ControllerAllTables" that can search through all tables.
HTML:
<form name="searchForm" id="searchForm" method="POST" action="ControllerAllTables.php">
Search for: <input type="text" name="aSearch">
<input type="submit" name="searchButton" value="Search">
</form>
PHP:
// Collect Data
// If an input has been given
if(isset($_POST["aSearch"])) {
$searchq = $_POST["aSearch"];
$searchq = preg_replace("#[^0-9a-z]#i","",$searchq); //Can only search words
// Select statements if keywords match
$sql = "SELECT * FROM insecttable WHERE insectName LIKE '%$searchq%'";
$sql1 = "SELECT * FROM butterflytable WHERE butterflyName LIKE '%$searchq%'";
$sql2 = "SELECT * FROM birdtable WHERE birdName LIKE '%$searchq%'";
}
// Tests if the code been inserted
if ($conn->query($sql && $sql1 &&sql2)=== TRUE){
echo "The rows you have searched for are:";
} else {
echo "Connection failed: ";
echo $conn->error;
}
// Show fields
$result = $conn->query($sql && $sql1 &&sql2);
// Output data of each row
if ($result-> num_rows> 0) {
readfile("ViewReturn.html");
while($row = $result-> fetch_assoc()) {
// echo "ID: ".$row["id"]. "<br>";
echo "Insect: ".$row["insectName"]. "<br><br>";
echo "Bird: ".$row["birdName"]. "<br><br>";
echo "Butterfly: ".$row["butterflyName"]. "<br><br>";
}
} else {
echo "0 results";
}
I cut out some of the bits of my code that didn't affect my question, like making connections and such.
At the moment, I have no idea how to return values in order, and I'm seriously stuck at searching multiple tables from one query. I've looked at "joins" but I really don;'t understand them.
As you can tell I'm not very good at PHP, and I hope I can soon rid it from my life. I've been completely unsuccessful in this section of my program and I'm looking for help and criticism. I know it's a lot to ask but I'm really stuck, thanks.
You'll want to use the UNION operator to combine the query results, being sure to order the data after it has been combined. This can affect performance, but hopefully your result sets aren't too large.
SELECT name -- because we NEVER use select *
FROM
(
SELECT insectName AS name FROM InsectTable WHERE insectName LIKE '$searchq%'
UNION ALL
SELECT butterflyName AS name FROM ButterflyTable WHERE butterflyName LIKE '$searchq%'
UNION ALL
SELECT birdName AS name FROM BirdTable WHERE birdName LIKE '$searchq%'
)
Also, you might want to consider a redesign of the database. If the items in your tables are all related then they are effectively a super class. If you Google "SQL super class design" you should be able to find some good patterns for this.
Also, appending the word "Table" to the end of all of your table names is not something that is usually done. If your table holds data about insects then it's "Insect" or "Insects" (I'll ignore the singular/plural debate for now). The fact that it's a table is already self-evident.

PHP - Getting num_rows of different ID's without writing new statements?

Basically, I'm coding a site that has many different categories and I want to display the amount of rows specific to that ID.
So for example, I have as the query:
$query= "SELECT job_sec FROM jobs WHERE job_sec = ?";
mysqli_num_rows($query);
I need to know how I can count the rows of an ID then echo the rows counted.
I'd like the results to display:
Web Design: 2,001 jobs
Logo Design: 5,120 Jobs
The job_sec column just uses a numerical value, would it be easier to have a text value then count the rows relating to the text value and echo them?
I have a feeling I need to use an array however I need the most efficient method.
Any help would be much appreciated!
Assuming job_sec is the category and I think you are looking for "group by":
$sql= "SELECT job_sec, count(*) AS c FROM jobs GROUP BY job_sec";
$r = mysqli_query($sql);
while ($row = mysqli_fetch_assoc($r)) {
echo $row['job_sec'] . ': ' . $row['c'] . ' Jobs ';
}
(didn't test and not sure if the mysqli syntax is correct)

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.

PHP while loop that prints sql content, with another query inside to another sql table?

I hope my title says something about what I am trying to do, I'll try to describe it a bit better:
I have a database with two tables, one named "movies" and another one named "directors".
Its a small movie database where we are supposed to be able to display all the movies, their title, year and producer.
In the table "directors" I have a field "id" and in my "movies" table i have a field named "producer" with the matching id. I want the while loop to loop thru all the movies in the "movies" table (working fine) and if i choose to print the "id" from "movies" its correct.
But now i want the loop to display the "title" and "year" from the "movies" table, and go to the "directors" table and get the name for the matching "id".
I'm new to both PHP and mysql queries and my code does this correctly for the first movie, but the rest have their "producer" field empty as for now.
(Right now I'm just trying to display the surname to see that it works).
FYI this is for a school project.
Code:
<?php
$sql = "SELECT * FROM movies ORDER BY title ASC";
$result = mysql_query($sql);
$row = mysql_fetch_assoc($result);
$id = $row['id'];
$num=mysql_numrows($result);
$i=0;
while ($i < $num) {
$title=mysql_result($result,$i,"title");
$year=mysql_result($result,$i,"year");
$producer=mysql_result($result,$i,"producer");
$id=mysql_result($result,$i,"id");
$sqldir = "SELECT * FROM directors WHERE id='$producer'";
$result1 = mysql_query($sqldir);
$row1 = mysql_fetch_assoc($result1);
$iddir = $row['id'];
$producertext = mysql_result($result1,$i,"surname");
?>
<b>Title:</b> <?php echo $title ?>
<br/><b>Year:</b> <?php echo $year ?>
<br/><b>Director:</b> <?php echo $producertext ?>
<br/>
</form> <HR>
<?php
$i++;
}
?>
Assuming that every movie has a single director then you can just create a joined query
SELECT movies.title as title, movies.year as `year` producer.surname as surname
FROM movies, producer where movies.producter = producer.id ORDER BY title ASC
You can then just walk the result set and the surname will be in the result arrays.
Here should be a complete solution assuming the query works as expected
<?php
$sql = "SELECT movies.title as title, movies.year as `year` producer.surname as surname FROM movies, producer where movies.producter = producer.id ORDER BY title ASC";
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result)): ?>
<b>Title:</b> <?php echo $row['title'] ?>
<br/><b>Year:</b> <?php echo $row['year'] ?>
<br/><b>Director:</b> <?php echo $row['surname]; ?>
<?php
endwhile;
?>
You are using wrong function
$num=mysql_numrows($result);
you should use
$num=mysql_num_rows($result);
You're accessing the producer information as:
$producertext = mysql_result($result1,$i,"surname");
However, $i is the index from the main SQL loop; so on the second run through, you'll be looking for the surname from the second line of your producer result set, which won't necessarily be there. So only the first producer is showing up.
Some other things you might want to look at - you can use PDO or mysqli to access data - they're more secure that mysql, which is in the process of being deprecated. You're also using mysql_fetch_assoc at the moment, but you don't seem to be using the resulting array for anything. It's a lot more common to go through a result set with something like:
while ($row = myssql_fetch_assoc($result)) {
....
}
Which loads the next row into an associative array for you to use, and stops when you run out of rows.
Also, have you considered what your code should do if there's more than one producer for a film? You might want to add a loop for that query, too.

Categories