I want to show all the posts from the people I am following including my own posts too. While it is working as intended, I have a problem: I get the same posts multiple times.
Here is my query:
SELECT posts.id, posts.body, posts.posted_at, posts.postimg, posts.likes, users.`username`
FROM users, posts, followers
WHERE (posts.user_id = followers.user_id OR posts.user_id = :userid)
AND users.id = posts.user_id
AND follower_id = :userid
ORDER BY posts.posted_at DESC;
Can anyone help me? Thank you in advance.
The reason is in this condition:
WHERE (posts.user_id = followers.user_id
OR posts.user_id = :userid)
For every user you are following, you will get all your own posts, thus creating duplicates of own posts.
You should use a UNION (ALL) query. To avoid the full query duplication, you can first select all user IDs in a subquery:
SELECT followers.user_id
FROM followers
WHERE followers.follower_id = :userid
UNION ALL SELECT :user_id
Then join it with your tables:
SELECT posts.id,
posts.body,
posts.posted_at,
posts.postimg,
posts.likes,
users.`username`
FROM (
SELECT followers.user_id
FROM followers
WHERE followers.follower_id = :userid
UNION ALL SELECT :user_id
) uids
JOIN users ON users.id = uids.user_id
JOIN posts ON posts.user_id = uids.user_id
You should try to use:
Select DISTINCT(fields)
From....
Where ...
The DISTINCT will show only one row for every equal results.
I think that your query is working like a cross join.
I hope this helps you, and sorry for my english.
Related
There are three tables, I would like to get the count of a user's total tweets and the count of likes his total tweets received.
I tried to combine two queries to get what I want but failed. Have looked through several previous questions but still can't figure it out.
Users table
id
name
1
User1
Tweets table
id
UserId (foreign key)
content
1
User1
hello
Likes table
id
UserId (foreign key)
TweetId (foreign key)
1
User1
hello
First query:
SELECT Users.name, Users.id, COUNT(Tweets.UserId) AS UserTweetCount FROM Users
LEFT JOIN Tweets
ON Users.id = Tweets.UserId
GROUP BY Users.id
ORDER BY UserTweetCount DESC;
Second query:
SELECT Users.name, Users.id, COUNT(Likes.UserId) AS UserTweetBeLikedCount FROM Users
LEFT JOIN Likes
ON Users.id = Likes.UserId
GROUP BY Users.id;
I tried like below but would get wrong UserTweetBeLikedCount counts. The counts would be UserTweetCount's, not UserTweetBeLikedCount's. When I ran two queries separately, it worked well. But when I combined them together, it didn't work right.
Don't know how to display the right counts. Can someone give me hints to solve this, please?
SELECT Users.name, Users.id,
COUNT(Tweets.UserId) AS UserTweetCount, COUNT(Likes.UserId) AS UserTweetBeLikedCount
FROM Users
LEFT JOIN Tweets
ON Users.id = Tweets.UserId
LEFT JOIN Likes
ON Users.id = Likes.UserId
GROUP BY Users.id
ORDER BY UserTweetCount DESC;
I recommend using correlated subqueries for this:
SELECT u.*,
(SELECT COUNT(*)
FROM Tweets t
WHERE u.id = t.UserId
) AS UserTweetCount,
(SELECT COUNT(*)
FROM Likes l
WHERE u.id = l.UserId
) AS UserLikeCount
FROM Users u
ORDER BY UserTweetCount DESC;
As a note: For performance, you want indexes on Tweets(UserId) and Likes(UserId).
I have this subquery where I am getting the posts of users that a user is following. This is the subquery.
$query = "SELECT * FROM `Posts` WHERE UserID IN
(
SELECT Followed FROM `Follow` WHERE Follower = ?
)
ORDER BY PostDate DESC
";
// on bind_param ? will be $userID
This works fine but I also want to get the user's own posts and then data from a profiles table so I'm probably going to ditch the subquery for some sort of join. I've used inner joins before however the profile/posts table have a common id 'UserID' but the Follow table does not. Would a full join work or would I have to use an AS ?
A union might be best.
SELECT * FROM posts WHERE UserID = ?
UNION ALL
SELECT P.*
FROM posts P
INNER JOIN follow F ON F.followed = P.UserID
WHERE F.follower = ?
I'm taking longer than I expected with an easy Query in MySQL. I think it's gonna be a nested query but I don't see it easily.
I have 3 tables: Users, Comments, and Businesses. Comments have business_id, and user_id as foreign keys.
So I want the result of users.name and comments.review, having the number of the business.
So my First (and wrong) attempt was:
SELECT users.name, users.image, comments.review
FROM reviews JOIN users JOIN businesses
WHERE reviews.user_id=users.id AND reviews.business_id=4;
I want to set that PrimaryKey.user_id is equal to ForeignKey.users.id.
From all of the comments, I want to take these which are from the business_id=4.
It gives me failiure with both 'WHERE' clauses. So not sure if I could fix this with a nested query or maybe with a JOIN clause?
Any help will be appreciated!
Thank you all. [Edited Query]
Try this out and let me know in case of any queries.
select c.name,c.image,a.review
from
comments a
inner join
(select * from buisnesses where buisness_id = 4) b
on a.buisness_id = b.buisness_id
inner join
users c
on a.user_id = c.user_id;
or
select b.name,b.image,a.review
from
comments a
inner join
users b
on a.user_id = b.user_id
where a.buisness_id = 4;
Give this a try:
SELECT
users.name,
users.image,
comments.review
FROM reviews
JOIN users
ON reviews.user_id = users.id
JOIN businesses
ON reviews.business_id = business.business_id
WHERE reviews.business_id=4;
Since you're not using any of the columns from the business table, you could probably drop it from the query:
SELECT
users.name,
users.image,
comments.review
FROM reviews
JOIN users
ON reviews.user_id = users.id
WHERE reviews.business_id=4;
I have a table posts with columns board_id, author_id, message. I have another table users with columns id, name, avatar_url.
I need to write a query to get all of the users that have posted on a given board, with no duplicates. The query should return the full user row (id, name, avatar_url).
I've tried
SELECT DISTINCT users.*, posts.author_id
FROM users
INNER JOIN posts
ON users.id = posts.author_id
WHERE posts.board_id = [desired board ID]
but that's giving me duplicates of each user.
There is also the possibility that my query is correct and I've goofed on something elsewhere...
Here's a simple query that will get you all the rows in users with post activity w/o duplication
SELECT * FROM USERS
WHERE id IN (SELECT author_id FROM posts WHERE board_id = [desired board]
You could also use your basic syntax with a distinct on everything you need distinct, e.g.:
SELECT DISTINCT users.*
FROM users
JOIN posts ON users.id = posts.author_id
WHERE posts.board_id = [desired board ID]
Just group by the user id, like so:
SELECT users.id, MIN(users.name), MIN(users.avatar_url)
FROM users
INNER JOIN posts
ON users.id = posts.author_id
WHERE posts.board_id = [desired board ID]
GROUP BY users.id
SELECT users.id, users.name, users.avatar_url, posts.author_id
FROM users
INNER JOIN posts
ON users.id = posts.author_id
WHERE posts.board_id = [desired board ID] GROUP BY users.id
This will get all found rows and then group them by the userid so each user id will appear just once, hence each user row [who posts on the board] will appear just once.
Yet better is use with annotation not for highlighted after IN, which defense against duplicate values. That's it.
i have this 4 tables:
posts{id,post,date}
comment{id, user_id,post_id, comment, date}
tag_post{tag_id,post_id}
users{user_id, email,pwd,username}
i want to make this complex query, i want to get the maxiumum number of commenters(users) from a certain topic:
i.e.
select the most commeneters(count) on posts that have been tagged with tag_id=39
LIMIT 5
thanks :))
What about something like this :
select users.user_id, count(*) as nb_comments
from posts
inner join tag_posts on tag_posts.post_id = posts.id
inner join comment on comment.post_id = posts.id
inner join users on users.user_id = comment.user_id
where tag_posts.tag_id = 39
group by users.user_id
order by count(*) desc
limit 5
It should get you the five users who commented the most on posts that have the tag 39.