How to fetch results from two tables? (MySQLi) - php

How do I retrieve results from two tables in MySQLi using the object oriented way?
I am trying to fetch user information for $stmt2 from $stmt. $stmt loads perfectly but $stmt2 doesn't because it isn't getting the results.
Here's the code for it:
<?php
if ($stmt = $conn->prepare('SELECT `id`, `kills` FROM `rp_stats` ORDER BY `kills` DESC LIMIT 6'))
{
$stmt->execute();
$stmt->bind_result($id, $kills);
while($stmt->fetch())
{
if ($stmt2 = $conn->prepare("SELECT `id`, `username`, `look`, `online` FROM `users` WHERE `id` = ?"))
{
$stmt2->bind_param("i", $id);
$stmt2->execute();
$stmt2->bind_result($id, $username, $look, $online);
$user = $stmt2->get_result();
}
global $stmt2;
echo '<div class="leaderboardWrap">
<div class="userAvatar" style="float: left;width: 50px;display: inline-block;height: 50px;background-image: url(\'https://www.habbo.nl/habbo-imaging/avatarimage?figure='. $look . '&size=m&headonly=1\');"></div>
<div class="leaderboardContainer">
<p style="padding-top: 6px;"><span class="username-rainbow"><a ng-click="progress()" href="/user/' . $username . '">' . $username . '</a></span></p>
<p style="margin-top: -9px;"><i>$' . formatWithSuffix($credits) . ' cash</i></p>
</div>
</div>';
}
$stmt->close();
}
?>
I want it to show 6 different users based on the user stat as the left image shows, but instead, I am getting the right image.

Try to use inner join in database to minimize fetch process of data:
SELECT `id`, `kills` FROM `rp_stats`
INNER JOIN users ON rp_stats.id = user.id
ORDER BY `kills` DESC LIMIT 6

You're using same column names in different tables, so a join conflicts by default. That's why you must use aliases, like so:
SELECT s.id, s.kills, u.username
FROM rp_stats s
INNER JOIN users u ON s.user_id = u.id
ORDER BY s.kills DESC LIMIT 6
Note! that I use user_id. This is the foreign key (reference) from rp_stats to users. I mean it's not correct to compare users.id with rp_stats.id. Using this construction, a user can always have max. 1 stat. You generate more flexibility to user a user_id column, which references to the user table.

"SELECT RS.`id`, RS.`kills`, US.`id`, US.`username`, US.`look`, US.`online` FROM rp_stats RS, users US WHERE US.`id`=RS.`id` ORDER BY RS.`kills` DESC LIMIT 6";
A normalized query could help out.

Related

Showing two different values depending on SESSION value in INNER JOIN

I have two different tables, one named users, and another named transactions. Transactions contains wallet1, wallet2, amount. Users contains user details such as firstname, lastname, and wallet. I am trying to display the corresponding first name and last name, depending on whether or not the SESSION_wallet is equal to wallet1 or wallet2 within transactions. I tried searching for a while, and came up with a solution for showing the correct display name for the first and last name making the transfer, however, I am trying to make it display the correct value for "Transfer to:"
Here is some of my code to get a better understanding of what I mean:
MySQLi Query:
$result2 = mysqli_query($link, "SELECT * FROM transactions INNER JOIN users ON transactions.wallet1 = users.wallet WHERE transactions.wallet1 = '" . $_SESSION["wallet"] . "' OR transactions.wallet2 = '" . $_SESSION["wallet"] . "' Order by transactions.id DESC LIMIT 5 ");
PHP Code:
<?php
if(mysqli_num_rows($result2) > 0)
{
while($row = mysqli_fetch_array($result2))
{
?>
The table that needs to display the transfer from, and transfer to:
<?php
if ($_SESSION["wallet"] == $row["wallet1"]) {
echo "<td>Transfer to ".$row["firstname"]." ".$row["lastname"]."</td>";
}
else if ($_SESSION["wallet"] == $row["wallet2"]) {
echo "<td>Transfer from ".$row["firstname"]." ".$row["lastname"]."</td>";
}
?>
Right now my tables are only showing the first and last name of the user that made the Transfer, however, I need it to display the first and last name of the user that the transaction is made to as well. The else if code is working correct, but the first part is not showing the corresponding value.
You will need to JOIN your transactions table to your users table twice, once to get each users name. Then to avoid duplicate column names overwriting the results in the output array, you will need to use column aliases. Something like this should work:
$result2 = mysqli_query($link, "SELECT t.*,
u1.firstname AS w1_firstname,
u1.lastname AS w1_lastname,
u2.firstname AS w2_firstname,
u2.lastname AS w2_lastname
FROM transactions t
INNER JOIN users u1 ON t.wallet1 = u1.wallet
INNER JOIN users u2 ON t.wallet2 = u2.wallet
WHERE t.wallet1 = '{$_SESSION["wallet"]}'
OR t.wallet2 = '{$_SESSION["wallet"]}'
ORDER BY t.id DESC
LIMIT 5 ");
Then you can access each user's names as $row['w1_firstname'] etc.:
if ($_SESSION["wallet"] == $row["wallet1"]) {
echo "<td>Transfer to ".$row["w2_firstname"]." ".$row["w2_lastname"]."</td>";
}
else if ($_SESSION["wallet"] == $row["wallet2"]) {
echo "<td>Transfer from ".$row["w1_firstname"]." ".$row["w1_lastname"]."</td>";
}
Note that ideally you should use a prepared query for this, for example:
$stmt = $link->prepare("SELECT t.*,
u1.firstname AS w1_firstname,
u1.lastname AS w1_lastname,
u2.firstname AS w2_firstname,
u2.lastname AS w2_lastname
FROM transactions t
INNER JOIN users u1 ON t.wallet1 = u1.wallet
INNER JOIN users u2 ON t.wallet2 = u2.wallet
WHERE t.wallet1 = ?
OR t.wallet2 = ?
ORDER BY t.id DESC
LIMIT 5");
$stmt->bind_param('ss', $_SESSION["wallet"], $_SESSION["wallet"]);
$stmt->execute();
$result2 = $stmt->get_result();

PHP MySQLi get columns from foreign key

I have the following tables:
'auktionen'
id|uid|typ(FK)|min|max|menge|...
'typen'
id|typ
1|Hack
2|Schredder
where typ in typen is just a textutal representation, which I would like to get.
$prep_stmt = "SELECT anzeigentyp, typ, holzart,
qualitaet, rinde, min, max, menge FROM auktionen WHERE uid = ?";
$stmt = $mysqli->prepare($prep_stmt);
$stmt->bind_param('i', $user_id);
$stmt->execute();
$stmt->bind_result($anzeigentyp, $typ, $holzart, $qualitaet, $rinde, $min, $max, $menge);
$stmt->store_result();
So when fetching all my results I want to get "Hack" instead of the referencing id (in case it is 1). I guess it needs some JOIN to be achieved and I tried it like this without success:
$prep_stmt = "SELECT anzeigentyp, typen.typ, holzart,
qualitaet, rinde, min, max, menge FROM auktionen WHERE uid = ?
JOIN typen ON auktionen.typ = typen.typ";
What is the proper way to do it?
You must move the where clause to the end and join the corresponding columns typen.id and auktionen.typ
select a.anzeigentyp, t.typ, a.holzart, a.qualitaet, a.rinde, a.`min`, a.`max`, a.menge
from auktionen a
join typen t on t.id = a.typ
where ...

php mysql select something and get columns from other tables

I'm using prepared statements and I need to "select" other table, apart from these two, to get data but I get this:
Fatal error: Call to a member function bind_param() on a non-object in C:\xampp\htdocs\views\user\referral.php on line 16
If I add in SELECT table1.* , table.* , "theothertable.*"
$stmt = $mysqli->prepare("SELECT friends.*, rc_usuario.* // or just *
FROM friends
INNER JOIN rc_usuario ON rc_usuario.id = friends.friendID
WHERE friends.userID = ?");
$stmt->bind_param('s', $connectedUserID);
This is working fine, I get what i need, but I also need to get data from another table and I can't make other select because i need it all in a while to print all the data together.
The question is, can I SELECT something like that from 2 tables and also get data from other table/s?
Thank YOU!
EDIT: Add the new statement:
if ($stmt = $mysqli->prepare("SELECT friends.*, members.*, account_type.*
FROM friends
INNER JOIN members ON members.id = friends.friendID
INNER JOIN account_type ON account_type.name = members.acc_type
WHERE friends.userID = ? AND members.acc_type = ?")) {
$stmt->bind_param('is', $connectedUserID, $connectedAcc_type);
$stmt->execute();
} else echo $mysqli->error;
You can join more tables by using another INNER JOIN, like as follows;
INNER JOIN rc_usuario ON rc_usuario.id = friends.friendID
INNER JOIN rc_another ON rc_another.col = friends.coljoin
Just make sure you select all the columns you want in the joined table.
It might also help to run your prepare statement in an if, like this;
if($stmt = $mysqli->prepare("SELECT ...")) { // ... where the rest of your query is
$stmt->bind_param('s', $connectedUserID);
$stmt->execute();
}
else {
echo $mysqli->error;
}
which will give you an idea of any problems with the SQL syntax.
Hope this helps.

Query inside of another query?

I've searched and found ways to do queries inside queries, but I have not found the right answer.
What I am trying to do is to fetch comments from the table called users_profiles_comments and by doing that I will get the field of '.$member["author"].'. Then I want to show who made the comment with their rank and a display picture.
But because there is no user details stored in the comments table because its for comments, I need to create a query inside of my query result where I can have this:
"SELECT * FROM users WHERE username = $member['author'] ORDER BY `id` ASC"
The '.$member["author"].' value comes from the main query but I need it so it can find fields in my users table.
$sql = "SELECT * FROM users_profiles_comments WHERE postid = '1' ORDER BY `id` ASC";
$stm = $dbh->prepare($sql);
$stm->execute();
$users = $stm->fetchAll();
foreach ($users as $row) {
print '
<img src="'.$member["profilepic"].'" style="float:left;margin-right:10px;" width="80px" height="85pxm">
<h4>'. $row["author"] .'
<small>'. $row["date"] .'</small>
</h4>
<p>'. $row["content"] .'</p><hr> </a></li>';
}
echo '
</div>
';
I hope you understand.
Edit:
The database.
users Table
http://img855.imageshack.us/img855/4387/qyjl.png
users_profiles_comments table
http://i.imgur.com/aKRF5MN.png
But because there is no user details stored in the comments table because its for comments
This is good. You do not want to have your database information duplicated in both tables (de-normalized data) - there is no need.
Generally a foreign key is added to inverse side of the relationship. This would mean you have a user_id column within your comments table, allowing you to select the data in one query using a JOIN
SELECT comment.*, user.name AS comment_author
FROM comment
INNER JOIN user ON user.id = comment.user_id
WHERE user.id = 123
Edit - I flipped to JOIN to return comments rather than users, (as you said "to fetch comments") however both ways will work, it just depends which side of the relationship you are on.
Edit 2 To respond to your comment;
How would I be able to show this on my PHP code on the result?
you can be more specific with the above query (not use *) and render it as follows :
$sql = "
SELECT
comment.`date` as comment_date,
comment.content,
user.name AS author_name,
user.profilepic as author_pic
FROM
users_profiles_comments as comment
INNER JOIN
user ON user.id = comment.user_id
WHERE
comment.postid = 1
";
//...
$comments = $stmt->fetchAll();
foreach ($comments as $comment) {
echo '<img src="' . $comment['author_pic'] . '"/>';
echo '<h4>' . $comment['author_name'] . '<small>' . $comment['comment_date'] .'</small></h4>';
echo '<p>' . $comment['content'] . '</p>';
}
You can select member name in SQL statement. You can try this query, this query will bring all the information from two table if users.username = users_profiles_comments.author
WAY 1:
SELECT t1.*, t2.* FROM
(
SELECT * FROM users WHERE username = '.$member["author"].' ORDER BY `id` ASC
) AS t1
LEFT JOIN
(
SELECT * FROM users_profiles_comments WHERE postid = '1' ORDER BY `id` ASC
) AS t2
ON t1.username = t2.author
Finally, do your foreach to print
===================================================================
WAY 2:
You can try this also-
SELECT *,
(SELECT profilepic FROM users WHERE users.username = users_profiles_comments.author) AS profilepic
FROM users_profiles_comments WHERE postid = '1' ORDER BY `id` ASC
And print profilepic using $row['profilepic'] in your foreach loop
=====================================================================
WAY 3:
SELECT t1.*, t2.* FROM
(
SELECT * FROM comments WHERE postid = '1'
) AS t1
LEFT JOIN
(
SELECT * FROM users
) AS t2
ON t1.author = t2.username
What I understand is that you need to get information about the user from another table called user_profile_comments, based on the user id (correct me if wrong: :-)). Use a left outer JOIN to fetch data from another table, limited on user id.
See http://www.w3schools.com/sql/sql_join.asp for more info.

Query works in mysqlyog query window but not in php script?

I have two tables I am selecting from them 1 I want to get the user information and 2 I want to get all images belonging to the user . but the query does not retrieve the images but in query window I get them . Also in the script if I decide to select from the images table the images are displayed but when I do the joining stuff it does not work. I know there is something am not doing well . please any help will be appreciated
Bellow is the code
$query='SELECT
tish_clientinfo.lastname, tish_clientinfo.address,
tish_clientinfo.firstname,
tish_images.image_name
FROM tish_clientinfo
INNER JOIN tish_images
ON tish_clientinfo.user_id = tish_images.user_id
WHERE user_id= '. intval($_GET['user_id']);
$result = $con->prepare($query);
$result->execute();
May be the server got confused about user_id. Try this
$query='SELECT
tish_clientinfo.lastname, tish_clientinfo.address,
tish_clientinfo.firstname,
tish_images.image_name
FROM tish_clientinfo
INNER JOIN tish_images
ON tish_clientinfo.user_id = tish_images.user_id
WHERE tish_clientinfo.user_id= '. intval($_GET['user_id']);
You just having a little problem just after the where clause on the user_id specify the table just like I have done in the bellow answer
$query='SELECT
tish_clientinfo.lastname, tish_clientinfo.address,
tish_clientinfo.firstname,
tish_images.image_name
FROM tish_clientinfo
INNER JOIN tish_images
ON tish_clientinfo.user_id = tish_images.user_id
WHERE tish_clientinfo.user_id= '. intval($_GET['user_id']);
$result = $con->prepare($query);
$result->execute();

Categories