Reputation: 2289
I have two database tables I am attempting to join (home_comments and profile_img). What I am trying to attempt is matching the user_id from the home_comments database to the profile_img database, in order to get the profile image from the person who commented. The query I wrote is not broken, as it is producing results, however, the queried results are showing all of the images each user_id has in the profile_img database.
Whenever a person uploads a profile_img, I just add it to the database and then simply call for the last one within it to display the profile_img. So, I am looking for the same concept to be implemented. The user's last profile_img to show.
Whenever I add LIMIT 1
to the end of the query it only allows one comment to show, total. All I need is for the last (DESC
) profile_img to show for each user, but still showing all of the comments. How could I accomplish this?
Initially I had the following query:
$select_comments_sql = "
SELECT *
FROM home_comments
ORDER BY id DESC
";
My attempt at the query
$select_comments_sql = "
SELECT c. *,
p.user_id, p.img
FROM home_comments AS c
INNER JOIN profile_img AS p
WHERE c.user_id = p.user_id
ORDER BY id DESC
";
Database setups:
home_comments
id, user_id, username, comment, date
profile_img structure:
id, user_id, img
Edit: I also just noticed that it is showing the same comment for each different photo in the database, so duplicated comments. Not sure if this has to do with the image issue.
SQL with query:
$select_comments_sql = "
SELECT c.*, p.user_id, p.img
FROM home_comments AS c
INNER JOIN (SELECT max(ID) as ID, user_ID
FROM profile_img
GROUP BY user_ID) PI
on PI.User_ID = C.USer_ID
INNER JOIN profile_Img p
on PI.user_ID = P.User_ID
and PI.ID = P.ID
ORDER BY C.id DESC
";
if ($select_comments_stmt = $con->prepare($select_comments_sql)) {
//$select_comments_stmt->bind_param("s", $user_id);
$select_comments_stmt->execute();
if (!$select_comments_stmt->errno) {
//echo "error";
}
$select_comments_stmt->bind_result($comment_id, $comment_user_id, $comment_username, $home_comments, $comment_date, /*$commenter_id,*/ $commenter_user_id, $commenter_img);
$comment_array = array();
while ($select_comments_stmt->fetch()) {
$comment_array[] = $comment_user_id;
$comment_array[] = $comment_username;
$comment_array[] = $home_comments;
$comment_array[] = $comment_date;
/*$comment_array[] = $commenter_id;*/
$comment_array[] = $commenter_user_id;
$comment_array[] = $commenter_img;
$commenter_img = '<img class="home-profile-pic" src=" '.$commenter_img.'">';
if ($home_comments === NULL) {
echo 'No comments found.';
} else {
echo $commenter_img;
echo $comment_username. "<br>";
echo $home_comments. "<br><br><br>";
}
Upvotes: 2
Views: 63
Reputation: 20737
I would imagine this should work but I have not tested it.
SELECT c.*, p.user_id, p.img, MAX(p.id) /* not sure if you need MAX(p.id) but try it with/without it here */
FROM home_comments c
LEFT OUTER JOIN profile_img p on p.user_id = c.user_id
WHERE p.id = MAX(p.id)
ORDER BY c.id DESC
Upvotes: 0
Reputation: 35323
One approach would be to use an inline view to generate a set of data consisting of the max ID for each user's photo then use this set to limit the photos for all users..
In the below I generate a dataset called PI containing the max ID of each profile image for each user. Then this is joined back to profile_img entire set to act as a limit; thus only returning the most recent photo for a user. This in essence ensures you have a 1-M relationship between comments and Photo_image. The many-to-many was what was causing the problem.
SELECT c.*, p.user_id, p.img
FROM home_comments AS c
INNER JOIN (SELECT max(ID) as ID, user_ID
FROM profile_img
GROUP BY user_ID) PI
on PI.User_ID = C.USer_ID
INNER JOIN profile_Img p
on PI.user_ID = P.User_ID
and PI.ID = P.ID
ORDER BY C.id DESC
Upvotes: 2
Reputation: 2617
If you're only running the query for one (or a few) users, the fastest way is probably to have a sub-select in your select
instead of using a join
, since you're not strictly 'joining' the data.
SELECT c. *,
(
SELECT p.img
FROM profile_img AS p
WHERE p.user_id = c.user_id
ORDER BY p.id DESC
LIMIT 1
) AS img
FROM home_comments AS c
WHERE c.user_id = x
This will avoid computing every user's most recent profile image when you're only ever fetching one (or a few), since having a nested query won't be able to join on an index.
Upvotes: 1