I have a table which links the userID and the friendID (which is another user) to say they are friends.
If User 1 adds User 24 as their friend, the first row in the below table will happen
If User 10 adds User 1 as their friend, the second row in the below table will happen
From there, even if User 1 is on either side, they are friends with the adjacent ID.
FRIENDS TABLE:
userID | friendID
-----------------
1 | 24
10 | 1
What I need to do now is: If User 1 is logged in, I need to display the people they are friends with. This query I have wrote:
SELECT DISTINCT (Users.username), friends.userID, friends.friendID FROM Users, friends WHERE Users.userID IN(SELECT userID FROM friends WHERE Users.userID = friends.userID) OR Users.userID IN(SELECT DISTINCT(userID) FROM friends WHERE Users.userID = friends.friendID)
Will bring back:
username | userID | friendID
-----------------------------
name1 | 10 | 1
name1 | 1 | 24
name2 | 10 | 1
name2 | 1 | 24
name1 = ID 1
name2 = ID 10
Is there a way where I can retrieve the logged in Users'friends (e.g. if ID #1 is logged in) whether they appear in the userID or friendID columns. and then, in this case, retrieve ID 24 and 10 because they are linked with ID #1, and then when it comes to displaying, eliminate ID # 1 from the list because it will bring up that they are friends with themselves.
Hope this makes sense and thank you in advance!
SELECT DISTINCT s.FriendId
FROM (
SELECT f.FriendId
FROM Friends f
WHERE f.UserId = #id
UNION ALL
SELECT f.UserId
FROM Friends f
WHERE f.FriendId = #id
) s
WHERE s.FriendId != #id
You may not need the last WHERE given that a user probably is not adding himself or herself as a friend.
While the way you are storing data may seem efficient, the following may be a better approach:
When a MUTUAL friendship is formed, enter the data twice: once as userID(1) friendID(24) and once as userID(24) friendID(1). The reason this approach may be good is that it makes your table reusable.
Presently your table is like facebook: if I am your friend then perforce you are also my friend: I see your activities; you see my activities. The design I explain allow you to use the table as both facebook and twitter: just because you are following my activities does not mean I want to follow yours.
Here's an easy way to do it with UNION. This also takes care of duplicates:
(SELECT userID
FROM friends
WHERE friendID = 1)
UNION
(SELECT friendID
FROM friends
WHERE userID = 1)
If you want to return usernames too, you can do your JOINs inside the subqueries:
(SELECT f.userID, u.username
FROM friends f
JOIN users u
ON u.userID = f.userID
WHERE f.friendID = 1)
UNION
(SELECT f.friendID, u.username
FROM friends f
JOIN users u
ON u.userID = f.friendID
WHERE f.userID = 1)
Related
I've got 2 tables: users & friends. I want to show each profile picture of the friends of the logged user, but loggedUser-friends match is in a different table (which is friends) than the one that contains the URI to the profile pictures (which is users).
My query now looks like this:
SELECT profile_picture FROM users WHERE
And now I have to complete the WHERE clause:
friend's table schema is the following:
id | user_id | friend_id
friends table's sample data:
1 | pino20 | sebo14
while users' table schema is
id | user_id | profile_picture
users table's sample data:
1 | pino20 | pino20/profile.jpg
With below query you get your frends userid and their profile picture.
select user_id , profile_picture from users WHERE user_id in( select friend_id from friends where user_id=$your_userid)
Above result can be achieved using join
SELECT NT.profile_picture FROM users AS NT JOIN friends AS FR ON FR.id = NT.id
You can achieve this by using joins. It should look like this:
EDIT:
SELECT user.profile_picture,user_friend.profile_picture
FROM user
JOIN friend ON user.user_id = friend.user_id
left join user user_friend on user_friend.friend_id=friend.user_id -- left join since we don't want to drop records if there is no match
I have two tables in my MySql database:
user
- sid
- userid
- username
log
- sid
- userid
- login_time
As you can guess, there's a lot more records in log tables than in user table.
I am using php to present these records on my website in a table format as shown below.
no | userid | username | number of login |
1 | inzo | harvey | 233 |
2 | chae | schmidts | 433 |
3 | hibro | swainy | 12 |
To get the number of login for each user, I can send another queries in a for statement. But it's consuming resources and making the server slow in the end.
Can I have this result in one single join query?
Yes you can, you have to use count the logins for each user with a group by
select t1.userid, t1.username, count(t2.sid)
from user t1
left join
log t2
on t1.userid = t2.userid
group by t1.userid, t1.username
The left join ensures you that users without logins will still be returned, wit 0 as count.
Edit
About the question in the comment: if you want to only count the logins with a specific flag value, you can just add where flag = x before the group by; if you want to have a separate count for each value of the flag, you have to add that flag to both group by and select.
I guess best and by that I mean least resource consuming way would be to add "number_of_login" to user table and just increase it every time he/she is logged in, because any other solution will require looping
SELECT TABLE_A.row_id, TABLE_A.category, TABLE_A.val_1, TABLE_B.val_2
FROM TABLE_B
LEFT OUTER JOIN TABLE_A ON TABLE_B.row_id = TABLE_A.row_id
ORDER BY row_id;
If you want all the results, you need an outer join, not an inner one.
select a.sid,a.userid,a.username,COUNT(b.sid) from user a
Left join log b ON b.sid =a.sid group by a.sid
I am using Laravel to creating a website, my users can post questions and other users can write their comments under the post, each comment have Up vote and Down vote, and users can voting for comments.
I need most liked (Up vote) shows topper than others..
This is my database structure and I join them together:
comment table:
comment_id | question_id | user_id | timestamp
up and down votes table (like):
like_id | comment_id | like_type | user_id | timestamp
note:like_type is an enum on mysql and its values are upvote and downvote.
1-What is the mysql query and Laravel codes for that?
2-Is my database Structure right?
1.Calculate SUM belongs to Each Comment
2.Make it order by Desc
select * from (
select ct.comment_id,ct.question_id,
ct.user_id,SUM(case when vt.like_type='upvote' then 1 else -1 end )
cnt from commenttable ct
from votestable
vt left join
on
vt.comment_id=ct.comment_id
)D order by D.cnt desc
I have a database with 4 tables:
users following
------------- --------------------------------
| id | etc.. | | user_id (FK) | follow_id (FK) |
articles article_relations
------------- --------------------------------
| id | etc.. | | user_id(FK) | article_id (FK) |
Users can follow other users so they can see what articles they saved.
So based on the current user id it needs to check which users he/she follows in the table "following". The users that are followed will be known now.
Based on those follower ids it needs to check in article_relations which article id's are linked in article_relations to the followers. Now it should now which articles are saved by which users.
So now in the table articles the article_ids needs to be queried keeping the information which user the article saved.
Is the database design logical?
It seems to me that querying the "stream" to see which articles the users you follow saved is very redundant.
Can someone tell me if the DB Design is OK and help me with the query to get the articles from
the users you follow including the user info?
I tried till my pants fell off and searched whole stackoverflow!
try this query, it'll get you user's information, and the people the current user is following's information and the articles that are saved by the people the current user is following.
SELECT u.*,
fu.*,
a.*
FROM following f
INNER JOIN users u ON u.id = f.user_id
INNER JOIN users fu ON fu.id = f.follow_id
INNER JOIN article_relations ar ON ar.user_id = f.follow_id
INNER JOIN articles a ON a.id = ar.article_id
WHERE f.user_id = <currentUserId>
just change the .* to fields you need from each table.
Structure looks fine to me. As for the query, try this.
Join the following table (a) to the article_relations table (b)
by way of the follow_id then joining that to the article table (c) by article_id all based on the current user id.
I'm including the fictional fields article_name and article_field just as an example of what you might be pulling from the article table.
select c.id,
c.article_name,
c.article_field
from (following a
join article_relations b on a.follow_id = b.user_id)
join articles c on b.article_id = c.id
where a.user_id = current_user_id;
Just need to add the users table (d) into the mix for that.
select c.id,
c.article_name,
c.article_field,
d.id
from ((following a
join article_relations b on a.follow_id = b.user_id)
join articles c on b.article_id = c.id)
join users d on a.user_id = d.id
where a.user_id = current_user_id;
I have one table which stores user info, including the username.
Another table contains a list of user id's and the user id's of those that they have favorited.
I am trying to figure out the query for listing the usernames of those that user id 1 has favorited.
In my query, assuming that I am uid 1, I need the usernames of uid 3 and 5, but instead
in sqlfiddle I am attempting to join them but I keep getting my username, cjaredrun, instead of the matched usernames for each favorite.
You can see what I have been trying here: http://www.sqlfiddle.com/#!2/c5836/1
Any guidance appreciated
You just need a simple join:
SELECT u.username FROM fav_user f
JOIN users u ON u.uid = f.matchuid
WHERE f.uid = 1
ORDER BY datetime
Fiddle here.
Output:
| USERNAME |
|----------|
| jolet |
| jane |