How to join three MySQL tables with unrelated data? - php

So I have a webpage that shows an image and information about it, and I also have three tables.
IMAGES USERS COMMENTS
id user_id id
user_id username user_id
username password comment
title isadmin date
image (location) points
description signup_date
points email
category city
bio
profile_image
I need to use all the information from the images and comments table. But I also need to retrieve the profile_image of the user that posted the comment and image. I cannot figure out how to do this: here is what I have so far.
$conn = new PDO ("mysql:host=localhost;dbname=project", "root", "pass");
$stmt = $conn->prepare("
SELECT images.*, users.profile_image, comments.*
FROM (images.id JOIN comments ON images.id = comments.id)
LEFT JOIN users
ON images.user_id = user.profile_image
");
Am I close? or trying the impossible here!?

it's a lot simpler then you'd think :)
the tables are NOT unrelated, they all have the same key - user_id and that's how you join them.
your query should look like this:
SELECT images.*, users.profile_image, comments.*
FROM images
JOIN users ON images.user_id = users.user_id
JOIN comments ON comments.user_id = users.user_id AND images.id = comments.id
this is assuming the images.id and comments.id match (I suspect they do not - but you did not give us enough info)
looking at your table structure, comments and images appear to have no connection, so maybe query them separately to avoid duplicated & confusing data
---UPDATE---
assuming you've added image_id to comments this is your query:
SELECT images.*, users.profile_image, comments.*
FROM images
LEFT JOIN users ON images.user_id = users.user_id
LEFT JOIN comments ON comments.user_id = users.user_id AND images.id = comments.image_id
what LEFT JOIN does is return 'images' that don't necessarily have 'users' or 'comments' connected to them.

I guess this will do the trick:
SELECT i.*, u.profile_image, c.*
FROM images i
LEFT JOIN comments c ON i.user_id = c.user_id
LEFT JOIN users u ON i.user_id = u.user_id

I think it's:
> SELECT images.*, users.profile_image, comments.*
> FROM images
> INNER JOIN users ON images.user_id= users.user_id
> INNER JOIN comments ON users.user_id= comments.user_id

Related

SQL - join selected data or table for conditions

I have SQL tables for users and relationships, like
users{ID, name, email}
relationships{ID, uid, relid, type}
I want to get all "friends" ID, name and email (by current user ID) by SQL, using JOIN or whatever.
If using join is it better to JOIN the table of users and select relationships or select relationships and join users?
something like this (I invented now, i use a bit diferrent tables and code, sorry for errors)
1:
SELECT DISTINCT u.ID, u.name, u.email FROM users u JOIN relationships r ON (r.uid = 1 OR r.relid = 1) AND r.type = 1 WHERE u.ID = r.uid OR u.ID = r.relid
2:
SELECT DISTINCT u.ID, u.name, u.email FROM relationships r JOIN users u ON r.uid = u.ID OR r.relid = u.ID = 1 WHERE r.uid = u.ID OR r.related = u.ID
Edit:
I use DISTINCT becouse when I select users whoose IDs equals to r.uid or r.related, I also get the current user (uid + related) for every relation. DISTINCT should unique the users? I'm beginner and found this on stackoverflow.
So, is it better to select from users and join relations or select relations and join users?
BTW: I quite like the answer with UNION
You can union the users where user is in the uid and in the relid.
SELECT users.*
FROM users
INNER JOIN relationships AS rel
ON users.ID = rel.uid
WHERE users.ID = 500
UNION
SELECT users.*
FROM users
INNER JOIN relationships AS rel
ON users.ID = rel.relid
WHERE users.ID = 500
Not sure why you are using DISTINCT but it looks like you just want to select all the rows from the relationships table (the friends), and then join their details from the users table.
SELECT u.id, u.name, u.email
FROM relationships r
LEFT JOIN users u ON u.id = r.uid
WHERE r.uid = 12345

database - Inner join with 3 tables in mysql issue

I'm doing a favorite system which allow users to save the posts to their page.
The tables I'm using are:
saved_posts table which contain 3 columns (painned_id``user_id``post_id)
users which contain (user_id, frist_name, last_name, username, email, password, user_website, user_avatar)
Finally posts table (post_id, user_id, post_author, category_id, post_date, post_image, post_avatar, user_website, post_keywords, post_content)
The my sql code I'm using to get the saved posrt
SELECT * FROM posts INNER JOIN saved_posts
ON saved_posts.post_id =
posts.post_id INNER JOIN users on saved_posts.user_id = users.user_id WHERE
saved_posts.user_id = users.user_id AND saved_posts.post_id = posts.post_id
The problem is that the saved posts from one user appears for other user as if they saved them as well.
Shouldn't you filter your answer with a WHERE condition? Otherwise it is just finding all posts that any user shared EVER.
SELECT * FROM posts
INNER JOIN saved_posts
ON saved_posts.post_id = posts.post_id
INNER JOIN users
ON saved_posts.user_id = users.user_id
WHERE users.user_id = :wanted_user_id
Don't forget to bind wanted_user_id.
If I understood the question correctly, the task is to select all the posts which of the users
SELECT * FROM posts p
INNER JOIN saved_posts sp ON p.post_id = sp.post_id
and sp.user_id = u.user_id
INNER JOIN users u on p.user_id = u.user_id

Difficulty with join 3 tables in a query in php

My database has 3 tables i wish to access in the select query but I cannot seem to get it to work. Selecting from 2 tables works fine so I know everything else is working apart from my code for selecting from 3 tables. My database has been created on PHPmyadmin
The Tables are as follows:
forum_replies
reply_id
topic_id
user_id
reply_text
reply date
forum_topics
topic_id
category_id
user_id
topic_title
topic_description
topic_date
users
user_id
username
This is the code I have tried to use and shows the fields I wish to select:
$queryreply = "SELECT forum_replies.reply_id, forum_replies.topic_id, forum_replies.user_id,
forum_replies.reply_text, forum_replies.reply_date, users.user_id, users.username
forum_topics.topic_id,forum_topics.topic_title, forum_topics.topic_date
FROM forum_replies
JOIN forum_topics
ON forum_replies.topic_id = forum_topics.topic_id
JOIN users
ON forum_replies.user_id = users.user_id
";
$result = mysql_query($queryreply) or die (mysql_error());
$row = mysql_fetch_array($result);
Example in code would be appreciated. Thanks
Use this query:
SELECT a.reply_text, a.reply_date, b.topic_title, c.username
FROM forum_replies a
LEFT JOIN forum_topics b ON a.topic_id=b.topic_id
LEFT JOIN users c ON a.user_id=c.user_id
// apply WHERE, ORDER, GROUP if needed
Apart from syntax errors, you should use LEFT JOIN and table alias in your case.
To show also the topic creator's username, you can adjust the query to the following:
SELECT a.reply_text, a.reply_date, b.topic_title, c.username AS reply_user, (SELECT username FROM users WHERE user_id=b.user_id) AS topic_creator
FROM forum_replies a
LEFT JOIN forum_topics b ON a.topic_id=b.topic_id
LEFT JOIN users c ON a.user_id=c.user_id
// apply WHERE, ORDER, GROUP if needed
You miss the , after users.username..
SELECT forum_replies.reply_id, forum_replies.topic_id, forum_replies.user_id,
forum_replies.reply_text, forum_replies.reply_date, users.user_id, users.username,
forum_topics.topic_id,forum_topics.topic_title, forum_topics.topic_date

PHP mysql how to relationship three tables showing outputs from different tables

I have this diagram
What I wanna do is have this output:
How do you manage to do the query of this one?
I have this code
SELECT users.firstname, users.lastname,
users.screenname, posts.post_id, posts.user_id,
posts.post, posts.upload_name,
posts.post_type, posts.date_posted
FROM website.users users
INNER JOIN website.posts posts ON (users.user_id = posts.user_id)
ORDER BY posts.pid DESC
//PROBLEM with this one is that it only views the post from all users.
//SO I added
SELECT COUNT(user_id) AS friends, SUM(user_id = ?) AS you, user_id
FROM feeds WHERE post_id = ?
//This one will give you two fields containing how many different users **feeds** the
post
Please help guys. Actually this one I am just following Facebook's "LIKE" status
the only thing is I'm not an amateur with this kind of stuff so I'd be glad to hear all your answers. I really need your help
If I've understood you correctly, you want an outer join with the feeds table (in order to retain all posts even if there are no associated feeds), then GROUP BY post.pid in order to amalgamate together all such feeds for each post, and SELECT the desired information.
I use MySQL's GROUP_CONCAT() function to obtain a comma-separated list of all users (up to group_concat_max_len) who have
a "feed" for the given post (you can change the delimiter with the SEPARATOR modifier, if so desired).
SELECT users.firstname, users.lastname,
users.screenname, posts.post_id, posts.user_id,
posts.post, posts.upload_name,
posts.post_type, posts.date_posted,
COUNT(feeds.user_id) AS friends, -- number of "likes"
SUM(feeds.user_id = ?) AS you, -- did I like this?
GROUP_CONCAT(feeds.user_id) -- who likes it?
FROM website.users users
INNER JOIN website.posts posts ON (users.user_id = posts.user_id)
LEFT JOIN website.feeds feeds ON (posts.post_id = feeds.post_id)
GROUP BY posts.pid
ORDER BY posts.pid DESC
UPDATE
To obtain the full name of users who have "liked" the post, excluding oneself, one needs to join the users table a second time:
SELECT users.firstname, users.lastname,
users.screenname, posts.post_id, posts.user_id,
posts.post, posts.upload_name,
posts.post_type, posts.date_posted,
COUNT(feeds.user_id) AS friends, -- number of "likes"
SUM(feeds.user_id = ?) AS you, -- did I like this?
GROUP_CONCAT(
CASE WHEN NOT likes.user_id = ? THEN -- exclude self
CONCAT_WS(' ', likes.firstname, likes.lastname) -- full names
END
)
FROM website.users users
INNER JOIN website.posts posts ON (users.user_id = posts.user_id)
LEFT JOIN website.feeds feeds ON (posts.post_id = feeds.post_id)
LEFT JOIN website.users likes ON (feeds.user_id = likes.user_id)
GROUP BY posts.pid
ORDER BY posts.pid DESC
If You want to do it for all the users and simultaneously get the feeds, You have to join this feed table:
SELECT u.firstname, u.lastname,
u.screenname, p.post_id, p.user_id,
p.post, p.upload_name,
p.post_type, p.date_posted,
COUNT(f.user_id) AS friends, SUM(f.user_id = ?) AS you
FROM website.users u
INNER JOIN website.posts p ON (u.user_id = p.user_id)
LEFT JOIN website.feeds f ON (p.post_id = f.post_id)
GROUP BY p.pid
ORDER BY p.pid DESC
This one should do the trick...

mysql - subqueries and joins

I'm not quite sure if this is the right approach, this is my situation:
I'm currently trying to select 15 galleries and then left join it with the user table through the id but I also want to select one random picture from each gallery however from what I know you can't limit the left join (picture) to only pick up one random picture without doing a subquery.
Here is what I got so far but its not working as it should:
SELECT galleries.id, galleries.name, users.username, pictures.url
FROM galleries
LEFT JOIN users ON users.id = galleries.user_id
LEFT JOIN pictures ON (
SELECT pictures.url
FROM pictures
WHERE pictures.gallery_id = galleries.id
ORDER BY RAND()
LIMIT 1)
WHERE active = 1
ORDER BY RAND()
LIMIT 15
I also tried to do this with Active Record but I got stuck after doing two left joins, is it possible to do get a subquery in here:
$this->db->select('galleries.id, galleries.name, users.id as user_id, users.username');
$this->db->from('galleries');
$this->db->join('users', 'users.id = galleries.user_id','left');
$this->db->join('pictures','pictures.gallery_id = galleries.id AND','left');
$this->db->where('active',1);
I hope its not to messy but I'm really starting to get confusing by all the sql queries..
Edit:
Active Record with CodeIgniter
You could fetch a random picture in a subquery:
select
g.name, u.username,
(select url from pictures p where p.gallery_id = g.gallery_id
order by rand() limit 1) as url
from galleries g
left join users u on g.user_id = u.id
where g.active = 1
Based on your comment, you could select a picture for each gallery in a subquery. This is assuming the picture table has an ID column.
select
g.name, u.username, p.url, p.name
from (
select id, user_id, name,
(select id from pictures p
where p.gallery_id = g.gallery_id
order by rand() limit 1) as samplepictureid
from galleries
where g.active = 1
) g
left join users u on g.user_id = u.id
left join pictures p on p.id = g.samplepictureid
SELECT
g.id,
g.name,
u.username,
p.url
FROM
galleries g
INNER JOIN (SELECT DISTINCT
gallery_id,
(SELECT url FROM pictures ss WHERE ss.gallery_id = s.gallery_id
ORDER BY RAND() LIMIT 1) AS url
FROM
pictures s) p ON
g.id = p.gallery_id
LEFT OUTER JOIN users u ON
g.user_id = u.id
WHERE
g.active = 1
This query will go out and select a gallery, then it will find any gallery with a picture (if you want to return galleries without a picture, change INNER JOIN to LEFT OUTER JOIN, and you'll be fine). After that, it joins it up with users. Now, of course, this puppy is going to return every frigging gallery for however many users you have (hoorah!). You may want to limit the user in the WHERE clause (e.g.-WHERE u.id = 123). Otherwise, you're going to get more results than you'd expect. That, or do an INNER JOIN on it.

Categories