More than one Foreign Key from the same table - php

I have a problem with this MySQL Statment. So basicly i have a table called games and i want to
display this table on my website. Table games has Foregin Keys like developer_id,
publisher_id, categorie_id, platform1_id, platform2_id, platform3_id, platform4_id, platform5_id.
I have 5 of platform because in Table platforms i have 5 records (PC, PS4, XB1, SWITCH, MOBILE). (If you guys know any better and easier solution to these platforms pls tell me.)
So now my output on my website works but for example instead of showing developer name it shows
it's ID. I know i have to INNER JOIN them and i probbably can INNER JOIN all foregin keys but the
platform one. Because i dont know how to INNER JOIN if you have more then one FK from one table.
If you need more info tell me. I will also include picture of my DB and my PHP code where i SELECT from table games.
$query = "SELECT * FROM games WHERE id = $id";
$result = mysqli_query($link, $query) or die(mysqli_error($link));
while ($row = mysqli_fetch_array($result)) {
echo '<tr>';
echo '<td>'.$row['developer_id'].'</td>';
echo '<td>'.$row['publisher_id'].'</td>';
echo '<td>'.$row['categorie_id'].'</td>';
echo '<td>'.$row['platform1_id'].'</td>';
echo '<td>'.$row['platform2_id'].'</td>';
echo '<td>'.$row['platform3_id'].'</td>';
echo '<td>'.$row['platform4_id'].'</td>';
echo '<td>'.$row['platform5_id'].'</td>';
echo '<td>'.$row['game_name'].'</td>';
echo '<td>'.$row['relese_date'].'</td>';
$intro = $row['introduction'];
$desc = $row['description'];
echo '<td>'.$row['rating'].'</td>';
echo '</tr>';
}
Picture of my DataBase

SELECT games.game_name, games.relese_date, games.introduction, games.rating, games.description, dev.name as developer, pub.name as publisher, (SELECT * FROM platforms WHERE platforms.id in (games.platform1_id,games.platform2_id,games.platform3_id,games.platform4_id,games.platform5_id)) as plats
FROM games
INNER JOIN developers AS dev ON dev.id = games.developer_id
INNER JOIN publishers AS pub ON pub.id = games.publisher_id
WHERE games.id = $id
Keep in mind that the platforms will be listed as a collection under the property plats, and each of those items will be an object of properties as.
E.X.
return object=>
developer_id
publisher_id
categorie_id
plats => [
platform1_id=>name,
platform2_id=>name,
platform3_id=>name,
platform4_id=>name,
platform5_id=>name
]
game_name
relese_date
introduction
description
rating

Related

Echo contents of JOIN SQL tables with MySQLi

I'm working on a system, and this module is supposed to echo the contents of the database.
It worked perfectly until I added some JOIN statements to it.
I've checked and tested the SQL code, and it works perfectly. What's not working is that part where I echo the content of the JOINed table.
My code looks like this:
$query = "SELECT reg_students.*, courses.*
FROM reg_students
JOIN courses ON reg_students.course_id = courses.course_id
WHERE reg_students.user_id = '".$user_id."'";
$result = mysqli_query($conn, $query);
if (mysqli_fetch_array($result) > 0) {
while ($row = mysqli_fetch_array($result)) {
echo $row["course_name"];
echo $row["course_id"];
The course_name and course_id neither echo nor give any error messages.
UPDATE: I actually need to increase the query complexity by JOINing more tables and changing the selected columns. I need to JOIN these tables:
tutors which has columns: tutor_id, t_fname, t_othernames, email, phone number
faculty which has columns: faculty_id, faculty_name, faculty_code
courses which has columns: course_id, course_code, course_name, tutor_id, faculty_id
I want to JOIN these tables to the reg_students table in my original query so that I can filter by $user_id and I want to display: course_name, t_fname, t_othernames, email, faculty_name
I can't imagine that the user_info table is of any benefit to JOIN in, so I'm removing it as a reasonable guess. I am also assuming that your desired columns are all coming from the courses table, so I am nominating the table name with the column names in the SELECT.
For reader clarity, I like to use INNER JOIN instead of JOIN. (they are the same beast)
Casting $user_id as an integer is just a best practices that I am throwing in, just in case that variable is being fed by user-supplied/untrusted input.
You count the number of rows in the result set with mysqli_num_rows().
If you only want to access the result set data using the associative keys, generate a result set with mysqli_fetch_assoc().
When writing a query with JOINs it is often helpful to declare aliases for each table. This largely reduces code bloat and reader-strain.
Untested Code:
$query = "SELECT c.course_name, t.t_fname, t.t_othernames, t.email, f.faculty_name
FROM reg_students r
INNER JOIN courses c ON r.course_id = c.course_id
INNER JOIN faculty f ON c.faculty_id = f.faculty_id
INNER JOIN tutors t ON c.tutor_id = t.tutor_id
WHERE r.user_id = " . (int)$user_id;
if (!$result = mysqli_query($conn, $query)) {
echo "Syntax Error";
} elseif (!mysqli_num_rows($result)) {
echo "No Qualifying Rows";
} else {
while ($row = mysqli_fetch_assoc($result)) {
echo "{$row["course_name"]}<br>";
echo "{$row["t_fname"]}<br>";
echo "{$row["t_othernames"]}<br>";
echo "{$row["email"]}<br>";
echo "{$row["faculty_name"]}<br><br>";
}
}

PHP MySQL - How to fetch the SELECT GROUP_CONCAT,GROUP_BY two table?

I have two database tables like this and want to fetch to my website like this(see the screenshot)
But I can only fetch one table. I don't know how to use group by with JOIN
here is my code
$sql = "SELECT photographer,GROUP_CONCAT(free_image)
FROM free_images_table
GROUP BY photographer";
$result = mysqli_query($conn, $sql);
while($row = mysqli_fetch_assoc($result))
{
$free_image = explode(',', $row['GROUP_CONCAT(free_image)']);
echo "<tr>";
echo "<td>".$row['photographer_id']."</td>"; ?>
<td>
<?php
for($i=0; $i < count($free_image); $i++ )
{
echo $free_image[$i];
}
?></td>
echo "</tr>";
}
The special table may not have photographer (my website require only freeimage, the special image is optional.
This could be done using a LEFT JOIN (added column aliases for simplicity in php) -
SELECT free_images_table.photographer,
GROUP_CONCAT(DISTINCT free_images_table.free_image) as free_images,
GROUP_CONCAT(DISTINCT special_images_table.special_image) as special_images
FROM free_images_table
LEFT JOIN special_images_table
ON special_images_table.photographer = free_images_table.photographer
GROUP BY photographer
LEFT JOIN is used when you have a record in the 1st table, but not always a matching record in the 2nd table
Then in php, you would create your special image cells the same as your free image cells
$free_image = explode(',', $row['free_images']);
$special_image = explode(',', $row['special_images']);
...
SELECT table_1.free_image, table_2.special_image FROM table1 INNER JOIN table_2 ON table_1.photographer = table_2.photographer
In this case can use INNER JOIN.
Add table name before the field and INNER JOIN with same photographer.

Which JOIN to use

I'm trying to get info from a table.
I have boards and sub-boards. The column sub_id in table board tells me whether or not the board is a sub-board or not. If it is a sub-board then the id of the parent board is the value, if it isn't then the cell is null.
I wrote this to display whether or not a board has any sub-boards:
<?php
$data = mysql_query("SELECT * FROM board WHERE sub_id='$boardId'")
or die(mysql_error());
while($info = mysql_fetch_array( $data ))
{
Print "<br>Sub-collections:<br>";
Print "<font size='5pt'><a href='/board/index/".$info['id']."'>".$info['board_name']." </a></font>";
}
?>
This works fine.
Now I want to write a similar code to name the parent board (if the board is a sub) but this is where I'm having trouble.
I came up with:
<?php
$data = mysql_query("select * from board WHERE id='$boardId' AND sub_id IS NOT NULL") or die(mysql_error());
$issub = mysql_fetch_array($data);
?>
then using...
<?php if(($issub)): ?>
<?php echo $issub['sub_id'] ?>
<?php else: ?>
<?php endif ?>
To display.
The problem is without a join I cannot show anything other than the id of the parent board. I don't know which columns to join in order to extract info like board_name etc.
EDIT:
popovitsj's suggestion:
<?php
$data = mysql_query("SELECT * FROM board b WHERE EXISTS(SELECT * FROM board WHERE b.id = sub_id)") or die(mysql_error());
while($info = mysql_fetch_array( $data ))
{
Print "<br>Sub-collection of:<br>";
Print "<font size='5pt'><a href='/board/index/".$info['id']."'>".$info['board_name']." </a></font>";
}
?>
This works to a certain extent. It correctly displays the parent board on the subboard page, but also displays it erroneously on the parent board page.
EDIT2:
After researching LEFT JOIN at Meier's suggestion I eventually got it to work using this code:
SELECT * FROM board a LEFT JOIN board b ON a.sub_id = b.id WHERE a.sub_id LIKE b.id AND a.id='$boardId'
Before I answer the question: are you 100% sure that the $boardid does not come directly from http and is therefore manipulable by the user, so your users can not start a sql injection?
The join you need is a "outer self join". Outer join because you also want to display boards that do not have a parent. Outer join is also named left join.
A self join because the table is joined to itself. The trick with the self join is to give the table different names in the statement, so you can distinguish between th parent and the child.
A quick google search for "sql outer self join" gave me this, which explains it quite nicely.
The example is with employees and managers, and the managers are also employees. So the example is quite similar to yours:
http://blog.sqlauthority.com/2010/07/08/sql-server-the-self-join-inner-join-and-outer-join/
There are different solutions to this. One possible one is:
SELECT * FROM Board b
WHERE EXISTS
(SELECT * FROM Board
WHERE b.id = sub_id);
Another possible solution could be this, this only shows 'root' parent boards. (boards with no parents themselves).
SELECT * FROM Board b
WHERE sub_id IS NULL;

PHP nested loops with foreign key table

This is a multi-part question. My database looks like this:
USERS
-id
-fname
-lname
COMPANIES
-id
-name
-type
PRODUCTS
-id
-product
-restaurant (foreign key to companies id)
-vendor (foreign key to companies id)
-user (foreign key to users id)
-transaction_date
Is this a good way to set up the database? I was thinking of having separate tables for restaurants and vendors but wanted them to use the same login page and rather than have to worry about UNION queries, I just select them by type. They see different information upon login so I have an if statement that says if type = r, show this else show that. Best way?
The second issue comes up when I want to show the information upon login. Say a vendor logs in, they will see a list of all the records that match their vendor id. However, I am seeing too many records because of my nested loop. For example, the table looks like this:
Date--Product--Restaurant--User
I am using this query:
$sql = mysql_query("SELECT products.*, companies.name, CONCAT_WS(' ', users.fname, users.lname) AS fullname FROM products INNER JOIN companies ON products.vendor = companies.id INNER JOIN users ON products.user = users.id WHERE company='$id' AND companies.type='$type'") or die(mysql_error());
$num=mysql_num_rows($sql);
$sql1 = mysql_query("SELECT products.restaurant, companies.name AS cname FROM products INNER JOIN companies ON products.restaurant = companies.id") or die(mysql_error());
$num1=mysql_num_rows($sql1);
$i = 0;
while ($i < $num) {
$j = 0;
while ($j < $num) {
$d = mysql_result($sql,$i,"transaction_date");
$p = mysql_result($sql,$i,"product");
$r = mysql_result($sql1,$j,"cname");
$u = mysql_result($sql,$i,"fullname");
<td><?php echo $d; ?></td>
<td><?php echo $p; ?></td>
<td><?php echo $r; ?></td>
<td><?php echo $u; ?></td>
$j++; }
$i++; }
$id and $type are session created values upon login. There are 4 example records currently in the table. Rather than showing just 4, it shows 16 because the values of $num and $num1 are both 4 and $num is looping $num1 four times.
How can I fix this problem and just show the 4 records?
Thank you for your help. Let me know if you need any clarification on any part.
Your database set-up may need a little rethink.
The reason I think this is that you need to know which company each user is in and you cannot have this within the products table as you have.
I would consider adding the foreign key to the users table like so (assuming one user has one company and one company has many users). I have also made some other suggestions, something like the below:
users
- id
- company_id
- first_name
- last_name
companies
- id
- name
- company_type_id
company_types
- id
- type
products
- id
- product_name
- company_id
transactions
- id
- user_id
- product_id
- transaction_date
they will see a list of all the records that match their vendor
Now you will notice I removed the vendor id from the above tables - This is because the vendor id is the same as the company id. There is no point having two separate relationship id's for the same thing (correct me if I'm mistaken)
So with the above changes we can list these records easily, as so:
<?php
$db = new PDO(/**Connection info here**/);
$stmt = $db->prepare("
SELECT
a.id AS product_id,
a.product_name
FROM
products AS a
INNER JOIN
companies AS b ON b.id = a.company_id
INNER JOIN
company_types AS c ON c.id = b.type_id
WHERE
b.id = :company AND c.id = :companyType
");
$stmt->bindParam(":company", $usersCompanyIdHere, PDO::PARAM_INT);
$stmt->bindParam(":companyType", $usersCompanyTypeHere, PDO::PARAM_INT);
$data = $stmt->execute();
while ($row = $data->fetch()) {
/** List of all the products for given company id**/
}
?>
I have changed you code to use PDO, I don't want to overload you with info here but I cannot stress enough the benefits of using the PDO over native mysql_* functions - Do a Google search, I can see lots of useful and relevant information in the top 10 results.

MySQL/PHP - Nested Select Issue - Need To Obtain Values From Both Tables

I just need help refining this script to give me the values from both tables joined on the ID.
Basically I want the ID from both tables and then be able to get the other values from both tables based on the IDs (if need be) and display them in a loop.
The code I have is below but won't work.
$select = myQ("SELECT * FROM users a WHERE EXISTS (SELECT 1 FROM `videos` b WHERE a.id = b.id GROUP BY b.id HAVING count(*) > 1) ");
$i=0;
while ($row = myF($select)) {
$resultsLoopArray[$i]["videos.id"] = $row["id"];
$resultsLoopArray[$i]["videos.vid"] = $row["vid"];
$resultsLoopArray[$i]["users.username"] = $row["username"];
$i++;
}
if (isset($resultsLoopArray)) {
$tpl->Loop("searchResultsLoop", $resultsLoopArray);
}
For now all I need is the username from the users table, the id and video id from the video table.
Can someone help by chance?
you question is bit confusing me..
As for my understanding I am posting this soultion..
If you have two tables users , videos then .
$sql = "SELECT users.username , videos.* from users, videos where users.user_id = videos.user_id";
this query will fetch all record from users and videos table where user id is present in videos tables ...

Categories