Join three tables in mysql database - mysql

I'm trying to join three tables in mysql. I have three tables called post, sharepost and user. I want to join sharepost and user to retrieve the first and last name of the user who shared the post and I want to join post and user to retrieve the first and last name of the original user of the post with other columns.
The post table has the following columns,
postID, title, description, userID, dateposted,likes.
The sharepost table has,
postid, shareuserid, dateshared,likes
The user table has,
userID, firstname, lastname, datejoined, email, password, birthdate.
postid in sharepost references postID from the post table.
The userID and shareuserid both refers to the same user table.
I want to retrieve the original user and the user who shared the post as well.
sample data for the post table are,
enter image description here
sample data for the sharepost table are,
enter image description here
sample data for the user table are,
enter image description here
The following query can retrieve the first and last name of the user who shared the post,
SELECT P.postID,P.userID, P.title, P.description, S.shareuserID,
U.firstname, S.dateShared, S.likes from sharepost S join post P
on S.postID=P.postID join user U on S.shareuserID=U.userID
I expect to retrieve the original user from the post table and the user who shared the post from the sharepost table as well but I only get the name of the shared user.
enter image description here

The following should do the trick:
SELECT p.postID,
p.userID AS author_id,
p.title,
p.description,
sp.shareuserid AS sharer_id,
sp.dateShared,
sp.likes,
u1.firstname AS author_forename,
u1.lastname AS author_surname,
u2.firstname AS sharer_forename,
u2.lastname AS sharer_surname
FROM post p
INNER JOIN sharepost sp ON p.id = sp.postid
INNER JOIN user u1 ON p.userID = u1.userID
INNER JOIN user u2 ON sp.shareuserid = u1.userID
It's worth noting though that I can't see any reference to likes in your schemas. Not sure if that's a typo?

Thanks to #BenM 's answer I managed to modify my query as the following which returned my expected results,
SELECT P.postID,
P.userID,
P.title,
P.description,
S.shareuserID,
U.firstname AS sharer_name,
U1.firstname as author_name,
S.dateShared, S.likes
from sharepost S
join post P on S.postID = P.postID
join user U on S.shareuserID = U.userID
join user U1 on P.userID=U1.userID

Related

mysql tables: Join to two tables in a request

Newbie here.. Here's what I'm trying to do.
I have a Posts table with the following columns
id, userid, bodyText, date
and I have another table for users users.
When users submit a post, the user-id saves into the "posts" table under "userid". Well, I want to display that users information, such as name and picture, on the posts using the "userid" to get each users information so that their name and picture shows along with the post they submitted.
Sorry if I'm not being clear, english is not my first language and like I said, I'm new at this and still trying to learn.
I had it where when they submit the post, their name and picture also saves into the "posts" table but I want to change it because if the user updates their name or picture, it will still show the name and picture they had when they submitted the post. I want their name and picture to update on the posts if they update their information on the users table.
What you are asking about is a JOIN. In general the Join will look like
SELECT p.id. p.bodyText, p.date, u.name, u.picture FROM posts as p INNER JOIN users as u ON p.user_id = u.id where p.id = 123;
This will select the post with the ID 123 from the posts table and joins the users information from the users table based on the user_id columns value from the posts table.
In Syntax this could be something like
$sth = $dbh->prepare("SELECT p.id. p.bodyText, p.date, u.name, u.picture FROM posts as p INNER JOIN users as u ON p.user_id = u.id where p.id = ?");
$sth->execute(array(123));
$red = $sth->fetchAll();

How to count a number from different table when there's no common field?

There are a user table and a user_follow table that describes which user.id is following/followed. I'd like to count the occurrences of that user is following and being followed.
The problem is that user_follow table doesn't have user_id as a foreign key, so I'm not able to join enter image description here the two tables by a common field. I've tried to use LEFT OUTER JOIN on user.id=user_follow.following_user_id and GROUP BY user.id, but it only counts the times of following(followed times is exactly the same as the following, which is not right).
The way to solve this is to join on USER_FOLLOW twice, once for Followed By and once for Following.
You haven't posted the structure of USER_FOLLOW, so this is a guess and you'll need to correct it to fit your schema.
select u.id, u.first_name, u.last_name
, count(f.following_user_id) as following_count
, count(fb.user_id) as followed_by_count
from user u
left_outer join user_follow f on where f.user_id = u.id
left_outer join user_follow fb on where fb.following_user_id = u.id
group by u.id, u.first_name, u.last_name

MySQL Join And Select Random Field

I want to join two tables and return a random field from the second table because there are multiple matches when joining.
For example. I have a users table and a user_posts table. I want to select each user's id, and a random post id and the post's message that they have in the user_posts table. Each user can have multiple posts in the user_posts table.
This answer explains what I'm trying to do, but it's not working. Here's my query:
SELECT user_id, post_id, message FROM (
SELECT users.id AS user_id, user_posts.id AS post_id, message
FROM users INNER JOIN user_posts ON users.id = user_id
ORDER BY RAND()
) AS a GROUP BY user_id
For testing, I added two rows in the user_posts table for user with id of 1 but it's retrieving the same post every time.
using cross apply to get random one post and join to users to display
select u.id,RandomPostbyUser.*
from users u
cross apply (
SELECT user_posts.id AS post_id, message
FROM users u1 INNER JOIN user_posts ON u1.id = u.id
order by RAND()
LIMIT 1) RandomPostbyUser

Show mutiple tables on a query

I'm currently storing tweets from twitter in a database and I'm storing the user fields in a separate table. I then have a foreign key which links the userid to the tweet. I'm wondering how I should show all of the information from both of the tables.
Use an inner join.
select *
from tweets inner join users on tweets.user_id = users.user_id
Select t.message, u.name, u.email
From Tweets t, UsersInfo u
Where t.userid = u.id
You don't give any schema info, so I've made assumptions.
select tweet, date, username from tweets
join user on user.id=tweets.userid;

Making a user profile activity feed

I need to build an activity feed to go on each users profile page showing what they have been doing on the site.
There is three tables: comments, ratings, users
I want the feed to include the comments and ratings that the user has posted.
in the comments and ratings table it stores the user id of the user who posted it, not the username, so in for each item in the news feed it needs to select from the users table where the user id is the same to retrieve the username.
All the entries in the feed should be ordered by date.
Here is what ive got even though i know it is not correct because it is trying to match both with the same row in the users table.
SELECT comments.date, comments.url AS comment_url, comments.user_id, ratings.date, ratings.url AS rating_url, ratings.user_id, users.id, users.username
FROM comments, ratings, users
WHERE comments.user_id=%s
AND comments.user_id=users.id
AND ratings.user_id=%s
AND ratings.user_id=users.id
ORDER BY ratings.date, comments.date DESC
JOIN. It seems you know that, but here's how:
SELECT * FROM comments LEFT JOIN users ON comments.user_id = users.id
Thus, as far as I can tell, you're trying to order two separate things at the same time. The closest I think I can come up with would be something like:
(SELECT comments.date AS date, users.username AS name, comments.url AS url CONCAT('Something happened: ',comments.url) AS text
FROM comments LEFT JOIN users ON comments.user_id = users.id
WHERE users.id = %s)
UNION
(SELECT ratings.date AS date, users.username AS name, ratings.url AS url CONCAT('Something happened: ',ratings.url) AS text
FROM comments LEFT JOIN users ON comments.user_id = users.id
WHERE users.id = %s)
ORDER BY date DESC LIMIT 0,10
Note that the columns of both parts of the union match up. I'm pretty sure that that is required for something like this to work. That's why I have that CONCAT statement, which lets you build a string that works differently between ratings and comments.