I have two tables
Users: (id, name)
Relations: (user_id, relation_id)
User_id and relation_id are both ids from the table users.
What I want is ro recover all users who are friend with a specific user.
And here is my sql command: that doesn't work:
SELECT *
FROM users
NATURAL JOIN relations
WHERE user_id IN (SELECT id FROM users WHERE name='John doe');
Could you help me?
SELECT users.*
FROM relations
INNER JOIN users
ON relations.relation_id = users.id
WHERE relations.user_id = 12345;
You can also get the id with a subquery, just as you did in your example:
WHERE relations.user_id IN (SELECT id FROM users WHERE name='John doe');
To get all the relations a person has , the following query will work..
SELECT * FROM users us JOIN relations re ON us.id = re.relation_id
WHERE re.user_id = (
SELECT id
FROM users
WHERE name = 'John doe'
)
Try this
SELECT * FROM users as a
JOIN relations as b on a.id = b.user_id
WHERE b.user_id IN (SELECT id FROM users WHERE name='John doe')
SELECT user_id
FROM relations re
JOIN users us
ON us.id = re.user_id
WHERE relation_id = (
SELECT id
FROM users
WHERE name = 'John Doe'
)
Side note: you can't use NATURAL JOIN here, 'cause there is no column that have the same name and type in the two tables.
isnt this just a matter of querying the relations tables by the userId you are looking for?
select *
from relations
where user_id = #IdYouArelookingFor or relation_id = #IdYouArelookingFor
SELECT friend.*
FROM users AS friend
JOIN relations AS r
ON r.relation_id = friend.id
JOIN users AS u
ON u.id = r.user_id
WHERE u.name = 'John doe' ;
Friends are people with the same relation_id?
SELECT a.name FROM users a JOIN relations b on a.id = b.user_id
WHERE b.relation_id in
(select relation_id from relations where id = 'userid of user you are looking for')
AND a.id != 'userid of user you are looking for'
If your logic is different pls tell how it is working
Related
I have the following schema of a Mysql database:
User(Id, FirstName, LastName, NickName, Etc.)
Request(SenderId, ReceiverId)
Friendship(Id1, Id2)
I consider friendship to be an undirected relation, which means that for every friendship, I insert it twice to the Friendship table. (Let me know if this is not a good idea, please).
What I am trying to retrieve is a list of users, who are not friends to a specific user (let me name him UserX), nor have a current request ongoing to/from him.
My initial trials led me to this:
SELECT User.Id, User.NickName, User.Picture FROM User
LEFT JOIN Friendship A ON User.Id = A.Id1
LEFT JOIN Friendship B ON User.Id = B.Id2
LEFT JOIN Request C ON User.Id = C.Sender
LEFT JOIN Request D ON User.Id = D.Reciever
WHERE User.Id <> ?
And, of course the placeholder is UserX's Id.
This doesn't work because, although the tuples that has friendships or requests with UserX are eliminated, The friends still appear because they have friendships with other users!
Thanks in advance.
If you want an efficient solution, use not exists multiple times:
select u.*
from user u
where not exists (select 1 from friendship f where f.id1 = u.id and f.id2 = ?) and
not exists (select 1 from friendship f where f.id2 = u.id and f.id1 = ?) and
not exists (select 1 from request r where r.SenderId = u.id and r.ReceiverId = ?) and
not exists (select 1 from request r where r.ReceiverId = u.id and r.SenderId = ?);
In particular, this can take advantage of indexes on:
friendship(id1, id2)
friendship(id2, id1)
request(SenderId, ReceiverId)
request(ReceiverId, SenderId)
This should have much better performance than solutions that union subqueries together.
Using a left join to a union list:
select *
from User u1
left join
(
select ID2 as id
from Friendships
where ID1 = 'UserX'
union all
select ID1
from Friendships
where ID2 = 'UserX'
union all
select Sender
from Request
where Receiver = 'UserX'
union all
select Receiver
from Request
where Sender = 'UserX'
) ux
on ux.id = u1.id
where ux.id is null
and ux.id <> 'UserX'
What if you collect all distinct IDs from table "request" and "Friendship" and then select records from Users ID not available in the above list.
SELECT Id, FirstName, LastName, NickName
FROM User
WHERE ID NOT IN
(
SELECT DSTINCT Id1 ID FROM Friendship
UNION
SELECT DSTINCT Id2 FROM Friendship
UNION
SELECT DSTINCT SenderId FROM Request
UNION
SELECT DSTINCT ReceiverId FROM Request
)A
I have 3 tables like so
Table 1: UserInfo
user_id userName
123 userOne
Table 2: Post
user_id postContent
123 This is test message
Table 3: LikePost
user_id likesPostId
123 This is test message
I would like to run a query to get total number of post likes, posts, and user information from those 3 tables.
I can do this for each one such as in Post table:
SELECT COUNT(*) FROM Post WHERE Post.user_id = '123'
and SELECT * FROM UserInfo WHERE UserInfo.user_id = '123'
Is anyone have better solution in just 1 query? Thank you so much!
Use a structured query (with subqueries) something like this.
SELECT u.user_id, u.userName, p.num postcount, l.num likecount
FROM UserInfo u
LEFT JOIN (
SELECT COUNT(*) num,
user_id
FROM Post
GROUP BY user_id
) p ON u.user_id = p.user_id
LEFT JOIN (
SELECT COUNT(*) num,
user_id
FROM LikePost
GROUP BY user_id
) l ON u.user_id = l.user_id
What's going on here? The two subqueries, for example
SELECT COUNT(*) num,
user_id
FROM LikePost
GROUP BY user_id
each generate a virtual table with either zero or one row per user_id, showing a count for each user_id. You then join those virtual tables to your UserInfo table.
Use LEFT JOIN because ordinary innner JOIN will suppress users that lack either posts or likes.
Try This
SELECT ui.userName,Count(p.*),
Count(lp.*) as TotalPostLikes
FROM UserInfo ui
INNER JOIN Post p on p.user_id=ui.user_id
INNER JOIN LikePost lp on lp.user_id=ui.user_id
WHERE ui.user_id = '123'
GROUP BY ui.userName
If you want to select Username, Post and Likes on post, try the following
SELECT ui.userName,p.postContent as PostContent,
(SELECT COUNT(lp.user_id) FROM LikePost lp
WHERE lp.user_id=ui.user_id) as Likes,
(SELECT COUNT(_p .user_id) FROM Post _p
WHERE _p .user_id=ui.user_id) as TotalPosts
FROM UserInfo ui
INNER JOIN Post p on p.user_id=ui.user_id
WHERE ui.user_id = '123'
Yes you can do it within one query using leftjoin on Post and LikePost like below
SELECT COUNT(*),User.userName FROM UserInfo as User
leftjoin Post as Post on Post.user_id = User.user_id
leftjoin LikePost as LikePost on LikePost.user_id = User.user_id
where Post.user_id = 123
group by Post.user_id
I have two tables as follows
user [ ID , username ]
relationship [ user1_id(FK) , user2_id (FK) , status ]
I am trying to get the username by using either user1_id or user2_id where the status = 1 from relationship table. user1_id and user2_id are both IDs from the user table. The following query is failing and I am not sure where it's going wrong.
SELECT
U.username,
(R.first_user_id, R.second_user_id AS friends)
FROM
user U,
`relationship` R
WHERE (R.`first_user_id` = {$userID} OR R.`second_user_id`)
AND (`status` = 1 AND U.ID = friends)
returns both names of users in a relationship with a status of 1.
this also assumes that if a relationship record exists, both users must be in the user table.
SELECT U1.UserName, U2.username
FROM Relationship R
INNER JOIN USER U1
on R.User1_ID = U1.user_ID
INNER JOIN USER U2
and R.User2_ID = U2.user_ID
WHERE R.Status=1
It looks like you may be trying to get the usernames of all users that have a relationship with a certain specified user, regardless of the order of user IDs in the relationship record. That could be this:
SELECT
U.username,
U.first_user_id,
FROM
user U
JOIN `relationship` R
ON R.first_user_id = U.ID
WHERE
(R.`second_user_id` = {$userID})
AND (`status` = 1)
UNION ALL
SELECT
U.username,
U.second_user_id,
FROM
user U
JOIN `relationship` R
ON R.second_user_id = U.ID
WHERE
(R.`first_user_id` = {$userID})
AND (`status` = 1)
If that produces duplicates (or could do) and you don't want it to do, then change the UNION ALL to a straight UNION.
I have succeeded based on xQbert answer:
SELECT
U1.username,
U2.username
AS user_friend
FROM
Relationship R
INNER JOIN
user U1
ON
R.first_user_id = U1.ID
INNER JOIN
user U2
ON
R.second_user_id = U2.ID
WHERE (R.`first_user_id` = {$userID} OR R.`second_user_id` = {$userID})
AND `status` = 1
I have this table that I hold userlist for my msn application. There's another table for the friendship where it has two foreign keys from userlist.
user: id, name, online, ip...
friend: id1, id2
I want the information of the users that are friend with a specific id.
I'm using this sql query:
SELECT (latest_ip, email, online, pass, status)
from im.user JOIN im.friend ON user.id = friend.id1
WHERE user.id = 5
what am i missing?
remove the parenthesis on your select clause, you don't need them
SELECT latest_ip, email, online, pass, status
from im.user
INNER JOIN im.friend
ON user.id = friend.id1
WHERE user.id = 5
UPDATE 1
you need to have extra join with the table user again since you want to get the informations of the user's friends.
SELECT c.*
from im.user a
INNER JOIN im.friend b
ON a.id = b.id1
INNER JOIN im.user c
ON b.id2 = c.id
WHERE a.id = 5
I need some help with query from multiple tables.
My database:
I have following tables:
1. users (user_id, user_name, ..) //user_name is unique.
2. guestbook_comments(owner_id, comment_author_id, comment ..)
3. profile_photo(profile_photo_id, user_id, path)
My problem:
I want to build a following query:
I have url like guestbook.php?user=sudeep. So i get user_name by $_GET['user']; user_name is unique (in the users table).
I want to display all entries from guestbook_comments for a specific owner_id (but i only know user_name, so i will need to find user_id from users table).
For each of the comment_author_id in guestbook_comments table, I want to get the his user_name from table users and path from profile_photo table.
My approach:
First I join users and guestbook_comments table to get all guestbook comments for a specific user_id. Then In the while loop I join users and profile_photo table to get user_name and photo path respectively.
I highly doubt if my approach is any efficient. Can you tell me if there is a right way to do that?
$sql = "SELECT u.user_id, g.owner_id, g.comment_author_id
FROM guestbook g
INNER JOIN users u ON u.user_id = g.owner_id
WHERE u.user_name = $user_name";
while($row = mysql_fetch_array( $result )) {
$author_id = $row['comment_author_id'];
$sql = "SELECT u.user_name, p.path
FROM profile_photo p
INNER JOIN users u ON u.user_id = p.user_id
WHERE u.user_id = $author_id;
//display comment text from guestbook, user_name from users, and photo from profile_photo
}
Am I missing something, or could you combine both joins at once and get all the data with 1 call to the database, rather than 2 calls per user?
$sql = "SELECT u.user_id, g.owner_id, g.comment_author_id, p.path
FROM guestbook g
INNER JOIN users u ON u.user_id = g.owner_id
INNER JOIN profile_photo p on u.user_id = p.user_id
WHERE u.user_name = $user_name";
Try a single query:
SELECT u.user_id, g.owner_id, g.comment_author_id, g.comment_text, c.user_name, p.path
FROM users u
LEFT JOIN guestbook g
ON u.user_id = g.owner_id
LEFT JOIN users c
ON c.user_id = g.comment_author_id
LEFT JOIN profile_photo p
ON p.user_id = g.comment_author_id
WHERE u.user_name = $user_name
From user, find guestbook entries, find commenters, find commenters' photos