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();
Related
Who can help me?
I have 4 tables posts, users, users details and comments.
Here is the strucutre:
posts
id
title
description
users
id
username
password
users_details
id
user_id
avatar
location
comments
id
post_id
user_id
parent
comment
posted
I have a query which i want to display comments on specific post.
This is what i written but avatar column it doesn't show any results. It seems i written it wrong on join or something.
SELECT comments.id as comment_id,
comments.user_id as user_id,
comments.post_id as post_id,
comments.parent as parent,
comments.comment as comment,
comments.posted as posted,
users_details.avatar as avatar,
users.username as username
FROM `comments`
LEFT JOIN users ON users.id = comments.user_id
LEFT JOIN users_details ON users_details.user_id = users.id
WHERE comments.post_id='60337'
ORDER BY posted ASC
Here is a screenshot of the table with results https://i.imgur.com/VQ8KwV1.png
I want to mention the avatar field it has a value for that user in users_details table so it should be displayed...
Thanks!
Two potential reasons I could tell causing this issue.
1. The users do not have an avatar.
Try: Select Avatar from Users_Details where User_Id in (2,9212) and make sure it returns some data.
2. The Primary/Foreign key being used for joining the tables is not matching
Run those queries below and ensure that they are returning the same users.
select * from users where id in (2,9212)
select * from users_details where user_id in (2,2912)
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
Could anyone please help me to write a query in mysql to fetch the videos posted by friends of a particular user. I have 3 tables (users,friends and videos) and the table structure are as follows.
users - id
friends - id, user_id [from user table], friend_id [from user table]
videos - id, user_id [from user table], video_name
For ex: User with id 1 has 3 friends 2,3,and 4 mapped in friends table. Each friends has posted 2 videos, mapped in videos table. So when I login as user 1, i need to list the videos posted by 2,3 and 4 with their details fetched from user table.
Thanks in advance
JOIN is what you are looking for. This can be used to "link" multiple tables based on what is common between them. This is the backbone of Normalization
The first part will be to link the "Friends" table back to the "Users" table. I am going to use a local variable (#UserID) and set it to be yours. I really don't know what information you will want from the friends information, so I am going to use generics for last name and first name in all of the queries
SET #UserID = 1 -- Your UserID
SELECT u.LastName, u.FirstName
FROM Friends AS f
INNER JOIN Users AS u ON f.Friends_ID = u.User_ID
WHERE f.User_ID = #UserID
Then the second part is going to be linking the Users to the videos. This query will return the user name information along with the names of all the videos:
SELECT u.LastName, u.FirstName, v.video_name
FROM Users AS u
INNER JOIN Videos AS v ON u.User_ID = v.User_ID
So now we have the basics. For your example you want a user to get all of the videos from all of their friends. We can actually combine these 2 queries into one query to get this:
SET #UserID = 1 -- Your UserID
SELECT u.LastName, u.FirstName, v.video_name
FROM Friends AS f
INNER JOIN Users AS u ON f.Friends_ID = u.User_ID
INNER JOIN Videos AS v ON u.User_ID = v.User_ID
WHERE f.User_ID = #UserID
I have a bit of a strange question.
First let me tell you i cannot change the way the database is made.
Some people before me made a really good job of messing some things up pretty bad.
Its a news site and there are editors in that can edit the news posts that others post.
also editors can post news them self.
Now the question.
I have a table for news.
id | news_username (who post news)
news_text Table
news_id | username | news_text
(Here user: can be editor of the news or a person who posted news)
User Table
username | title
In that table there is a news 'id' and a news 'username'.
The username being the username of the user posting the news.
there are also allot more fields inside the table but they are not important.
Then there is a table news_text and within it the text for the news is placed.
This table has a 'news_id' and 'username' field.
This time the username is the field of the person who posted the news OR the username of the user that edited the post.
Then i have a user table with also a 'username' field and a 'title' field with the title for the user.
In this
Hope your still with me.
In short if a user posts a news article the text will be inside the 'news_text' table and when an editor edits the post the altered text will be inserted as a new text for the same article.
This is done to let the original poster see what was altered to his post.
now comes my challenge.
I need to figure out how i can get the number of edits that an editor made.
BUT because the editor itself can post news that means that i need to search for all news where the username is not equal to the original poster and where it is look for duplicates in the news_text table to see of the editor has edited his own post.
i really hope people understand a little of what i need to do.
hope you can help me.
in the comment Marcus Adams pointed me at the how the latest edit was used on the website.
This is don through a date/time field.
When an edit is placed the edit will be inserted into the news_text field and there will be date/time stamp for the new edit.
And with that it will determine witch text to grab for the news item.
hope this is clear
If I understand correctly, something like this should give the total number of edits all users have made but only where they were on posts that weren't themselves
SELECT
user.*,
COUNT(*) AS edits
FROM user
// Join posts that aren't this users
INNER JOIN news
ON news.username != user.username
// Join edits for the above posts that are this users
INNER JOIN news_text
ON news_text.news_id = news.id
AND news_text.username != user.username
And with a placeholder if you want to select a specific news article
SELECT
user.*,
COUNT(*) AS edits
FROM user
// Join posts that aren't this users
INNER JOIN news
ON news.username != user.username
AND news.id = [[SPECIFIC ID]]
// Join edits for the above posts that are this users
INNER JOIN news_text
ON news_text.news_id = news.id
AND news_text.username != user.username
Or maybe if you want to see how many edits a specific user has done on a specific article
SELECT
user.*,
COUNT(*) AS edits
FROM user
// Join posts that aren't this users
INNER JOIN news
ON news.username != user.username
AND news.id = [[SPECIFIC ID]]
// Join edits for the above posts that are this users
INNER JOIN news_text
ON news_text.news_id = news.id
AND news_text.username != user.username
WHERE user.username = [[SPECIFIC USERNAME]]
EDIT Alternative approach, if you want to count up all posts made by a user that ARE NOT original posts i.e. all edits, even if they are editing their own post
SELECT
user.*,
news.*,
COUNT(*)-IF(news.username=user.username,1,0) AS edits
FROM user
// This join will give us all posts made by user
INNER JOIN news_text
ON news_text.username = user.username
// Also join the news id
INNER JOIN news
ON news_text.news_id = news.id
GROUP BY user.username, news.id
This will return 1 row per user per news.id counting the number of edits a user has made against it, so to take this and return totals you could instead do this to return the number of edits performed by a single user by name
SELECT
username,
sUM(edits)
FROM (
SELECT
news_text.username.username,
COUNT(*)-IF(news.username=news_text.username,1,0) AS edits
FROM news_text
ON news_text.username = [[USER TO CHECK]]
// Also join the news id
INNER JOIN news
ON news_text.news_id = news.id
GROUP BY news.id
)
I would suggest that the easiest way to do this is in two queries:
One to find the total number of changes made by a user
e.g. SELECT COUNT(*) FROM news_text WHERE username = {USERNAME} GROUP BY username
And then one to find the total posts created by that user
e.g. SELECT COUNT(*) FROM news WHERE username = {USERNAME} GROUP BY username
And subtract one from the other.
Or do queries for all users and just take out the ones you need. (Or combine them into one query if you really want).
As I understand it, you have duplicate news_text rows for a particular news item (news_id). Also, you have an edit_date field on news_text table, and you're getting the news_text with the latest edit_date to get the latest version of the news item.
I also understand that you want the to get the number of edits from each user, excluding self-edits.
Here's one solution. This is for a particular user:
SELECT COUNT(*) AS edits
FROM user u
JOIN news n
ON n.username <> u.username
JOIN news_text nt1
ON nt1.news_id = n.news_id
AND nt1.username = u.username
JOIN news_text nt2
ON nt2.news_id = n.news_id
AND nt2.edit_date < nt1.edit_date
AND nt2.username <> u.username
LEFT JOIN news_text nt3
ON nt3.news_id = n.news_id
AND nt3.edit_date > nt2.edit_date AND nt3.edit_date < nt1.edit_date
WHERE u.username = 'myuser'
AND nt3.news_id IS NULL
First, it gathers all the news items that weren't authored by the user (ON n.username <> u.username)
Then it gathers all the news_texts for each of those news items that our user edited (ON nt1.news_id = n.news_id AND nt1.username = u.username)
Then it gathers all the previous versions for the above that are from other users (ON nt2.news_id = n.news_id
AND nt2.edit_date < nt1.edit_date AND nt2.username <> u.username)
Then it gathers any versions between the current one and the previous one, for exclusion later (ON nt3.news_id = n.news_id
AND nt3.edit_date > nt2.edit_date AND nt3.edit_date < nt1.edit_date)
Then it filters for our user (WHERE u.username = 'myuser')
Then it filters out edits that were in between the current and the previous, ensuring we only have the version just prior (nt3.news_id IS NULL)
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.