Multiple table join, facebook like news wall - php

Ok I am creating a social networking site similar to Instagram. So I want to fetch post from db but only show posts from people the currently logged in user is following just like Instagram. I've tried using a php join and it didn't work, though I think my query is wrong because it's bringing out false results. Please any answer to this would be nice as it would also help others. This is what I've tried to do but don't know where am wrong.
$query = $database->prepare("SELECT n.*, c.*, n.id AS nid, c.id AS cid FROM
newsfeeds n JOIN connections2 c ON c.user1 = n.userId OR c.user2 = n.userId
WHERE n.userId = c.user1 OR n.userId = c.user2 ORDER BY nid DESC");
$query->execute();
I have two table. One is connections2 for users connection and the other is newsfeeds table for post.
This is an image of my db
This one for connections table
this is where all followed people would be
This one for feeds table
This is the post table

Would this query work?
SELECT n.id AS nid,
n.userid,
n.news,
n.news_image,
n.access,
n.date,
c.id AS cid,
c.user1,
c.user2,
c.time,
c.status
FROM newsfeeds n
INNER JOIN connections c ON (c.user1 = n.userid OR c.user2 = n.userid)
ORDER BY n.id DESC;
However, why are you checking the connections table, and why are you checking it for two users? Wouldn't it be easier to check just the newsfeed table for the currently logged in user? Unless is misunderstand your connections table, this could work:
SELECT n.id,
n.userid,
n.news,
n.news_image,
n.access,
n.date,
FROM newsfeeds n
WHERE n.userid = "X"
ORDER BY n.id DESC;
(Replace the "X" with your actual user ID for the currently logged in user)

Related

How to join 3 tables with different data between them?

I'm not too good with explaining things, apologies.
I have 3 tables that are similar to the below:
users
id
username
threads
id
title
user_id
lastpost_id
posts
id
content
thread_id
user_id
On a page listing forum threads, I want the username of both the thread author, and the last post author of that thread to be displayed, I'm attempting to achieve this in a single query.
My query looks like this:
SELECT t.*,u.username FROM threads t
INNER JOIN users u ON t.user_id=u.id
INNER JOIN posts p ON t.lastpost_id=p.id
ORDER BY t.id DESC
The first join enables me to get the username of the user id that started the thread.
The second join is what I'm not sure on, it can get me the user id but how do I get the username from that, as a 3rd join?
You can select the same table multiple times if you give it a different alias. You can give the fields aliases too:
SELECT
t.*,
tu.username as threadusername, /* Result field is called 'threadusername' */
p.*,
pu.username as lastpostusername
FROM threads t
INNER JOIN users tu ON t.user_id=tu.id /* thread user */
INNER JOIN posts p ON t.lastpost_id=p.id
INNER JOIN users pu ON p.user_id=pu.id /* post user */
ORDER BY t.id DESC
You can join to a joined table like this:
SELECT t.*,u.username,u2.username FROM threads t
INNER JOIN users u ON t.user_id=u.id
INNER JOIN posts p ON t.lastpost_id=p.id
INNER JOIN users u2 ON p.user_id=u2.id
ORDER BY t.id DESC
Note, I haven't had time to test it, but it should work (at least in MySQL).
I don't know if I got it correctly, but as per my understanding you can have a inner query to fetch the thread ids and then have a outer query to fetch the posts based on the thread id, have a max on post id and group by user id. Also join to user to have the name. Hope that helps.

lowering MySQL load and memory usage

I'm working on new script. It's something similar to 9gag, there are posts and people like/dislike them and so on.
I have 3 tables for posts, users, like_status
for example:
posts table structure:
postid, postdata , userid, ...
users table stucture:
userid, username , ....
like_status
postid,userid,liked, disliked
I used to use MySQL query
SELECT A.*, B.username FROM posts A, users B WHERE A.userid=B.userid
then I get the like status by assigning the session userid to a variable $SID and use this MySQL query
SELECT * FROM like_status WHERE userid=$SID
everything is working fine, but I'm a little concerned about the server load.
Which is better for server load and memory, to run joining query to be :
SELECT A.*, B.username, C.liked, C.disliked
FROM posts A
JOIN users B ON (A.userid = B.userid)
JOIN like_status C ON (C.userid = $SID)
And what about if I'm using that query to fetch number of posts like 10 posts for example
SELECT A.*, B.username, C.liked, C.disliked
FROM posts A
JOIN users B ON (A.userid = B.userid)
JOIN like_status C ON (C.userid = $SID)
ORDER BY A.postid limit 10
.. Will it cause any performance issues?
That's it.
Best Regards

Complex Mysql query to combine 3 tables Data?

I have a table in which I store followers, I have another table in which I store friendships
Now I have third table which stores stream data.
Its a social network, there are many reasons so I don't wish to have one table for follower & friendships (Means facebook subscriptions/friends)
Can someone presents a way how should I query streams table to pick activities of both friends & followings ?
Any help would be really appreciated, thank you
Here is simple Database Scheme, its not really like this but almost!
Okay here is database tables schema please,
Followers table.
Row_ID
User_ID
Following_User_ID
Friends Table
Row_ID
User_ID
Friend_ID
Stream Table
Row_ID
User_ID
Contents_ID
Time
Type
What are you looking for is probably best done as two distinct results sets... or a union of the two.
Select "friend" as src, author, post from friends f inner join streams s on s.author = f.id
union
Select "follower" as src, author, post from followers f inner join streams s on s.author = f.id
This is just some pseudo coding but it should give you an idea of how to proceed. Without knowing your database schema, this is the best I can offer.
Edit:
This might be what your looking for then
select user_id, contents_id, time from (
select user_id, contents_id, time
from followers f inner join stream s on s.user_id = f.user_id and f.user_id = "username"
union
select user_id, contents_id, time
from friends f inner join stream s on s.user_id = f.user_id and f.user_id = "username"
) order by time desc
This will return the data in time order, descending.

MySql If Record Exists Inside Select Query

Creating a forum-type site and I have 3 tables, one for storing user information (users), one for the original post (threads), and one for an upvote system like SO has (votes).
The votes table has 3 columns, id, userid, and threadid. When a user upvotes a thread, a record is inserted into the votes table. When I query for the thread I want to know if the user has upvoted for it, essentially if a record exists in the votes table with the correct userid and threadid. I can do this in two queries, but I think there has to be a way to get everything in one.
My query currently:
"SELECT t.id, t.title, t.content u.id AS uid, u.username
FROM threads t, users u
WHERE t.id = '".$userid."'
AND t.author = '".$userid."'"
In case you need a better idea, the following will query the desired results ONLY if the user has upvoted. I need the query to still return if the record in the votes table doesn't exist (possibly return a vote value as null?).
"SELECT t.id, t.title, t.content u.id
AS uid, u.username v.id
FROM threads t, users u, votes v
WHERE t.id = '".$threadid."'
AND t.author = '".$userid."'
AND v.threadid = t.id
AND v.userid = '".$userid."'"
Also I taught myself (and am still learning) mysql and database design so if there's a better method/approach such as joining tables, please let me know. Thanks.
Your second query is doing inner joins, which would only return records that appear on both sides of the join. You'd want to do a left/right outer join on the votes table instead, so that you'd still get user+thread records even if there's no matching vote record.
SELECT t.id, t.title, t.content, u.id, u.username, v.id
FROM threads AS t
INNER JOIN users AS u ON t.userid = u.id
LEFT JOIN votes AS v ON (v.userid = u.id and t.id = v.threadid)
WHERE (u.id = $userid) AND (t.id = $threadid)
just guessing at this, but should be enough to get you started.

Get results from my own and "friends" posts

I have a problem that I can't figure out myself. I've tried using LEFT JOIN etc but nothing seems to work. I'm using MySQL so you know.
I'm building a little blogportal for me and my friends and all users have their own blog.
database:
users:
id,
username,
password,
etc
blog:
id,
title,
text,
user_id,
etc
relations
follower_id,
following_id
I query my own blogposts like this:
SELECT * FROM microblog WHERE user_id = {$user_id} ORDER BY posted DESC
and i list my friends like this:
SELECT * FROM users, relations WHERE relations.follower_id = {$user_id} AND relations.following_id = users.id
That was the easy part. BUT.
I rather JOIN the tables somehow because I also want to list my friends blogposts inside my loop. But I don't just want the post to show, I also want some info about the user that posted that one so then I must get some info from the users table as well. And that's what bothers me! I can't figure it out.
In short: I want to list my own blog posts and all the users I'm friend with within my own loop. And I also want to display username and email beside the posts.
Hope you understand what I mean.
/Tobias
Sweden
How about?
select
u.username,
u.email,
m.title,
m.text
-- ... etc
from microblog m
inner join user u on m.user_id = u.id
where m.user_id = {$user_id}
or m.user_id in (select
following_id
from relations r
where follower_id = {$user_id}
);
From my perspective I would pull the user data separately, store them into an array and access them when needed. This should be better for performance and would definitely be simpler.
select * from blog b, relations r
where b.user = $user_id or ( b.user = r.follower_id and r.following_id = $user_id )
order by posted desc;
Not sure if I reversed follower/following.
Try this?
SELECT m.*
FROM microblog m
INNER JOIN users u ON m.user_id = u.user_id
LEFT JOIN relations r ON r.following_id = m.user_id
WHERE m.user_id = {$user_id}
OR (r.follower_id = {$user_id} AND NOT IsNull(r.follower_id))
ORDER BY posted DESC

Categories