For a social network site, I have a table with the ids of the inviter and the invitee and the status of the invitation ie accepted or not. According to what I've read, this seems to be best practice for a friends table.
Table friends
id | inviterid |inviteeid |status
however, for a given userid, I want to display all the "friends" the person has including their names. I can get a list of records of relationships with a simple query
Select * from friends WHERE inviterid = '33' or inviteeid = '33'"
But, this does not translate easily into a list of friends, since the friends could be either inviters or invitees so the field will be different depending on who invited whom.
Is there a better table design for a friends table? Alternatively, is there a sql syntax that would select friends who can be either inviters and invitees. Ultimately, I need to do a join to another table that has the users names.
You have a user table with below colums
userId|name|...
and your friend table
id | inviterid |inviteeid |status
if you want to find friends of a user that this user invited themes you can use below query!
select id, status from friend_tbl inner join user_tbl on user_tbl.id=friend_tbl.inviterid;
or if you want to get friend of this user that themes invitee his/her you can use below query:
select id, status from friend_tbl inner join user_tbl on user_tbl.id=friend_tbl.inviteeid;
I hope these can help you and i can understand your purpose!
Use union to get two kinds of friendS together, then you can join the results with username table.
Select inviterid as friend_id, status from friends where inviteeid = 33
Union
Select inviteeid as friend_id, status from friends where inviterid =33
I personally would just prefer to have two tables for this case, friend table and invite table
Friend Table
id | userid | friendid
So for selecting friends would be just
SELECT friendid FROM friend_table WHERE userid = 33
Invite Table
id | inviterid | inviteeid | status
For changing the status of invite table once the user approves, and insert new row to friend table
UPDATE invite_table SET status = 'accepted' WHERE inviterid = 33
INSERT INTO friend_table (`userid`, `friendid`) VALUES (33, $friendid)
Related
I have 3 tables :
Person table stores basic person wise details with ID as primary Key
This person can have relationships (father / mother etc), which are saved in Relationship table, however the users for them are created in Person table (e.g. ID = 2,3 in person table), This way we know that 2,3 are related to user 1 (carry).
We also have 3rd table - address, which store user ID wise addresses.(for both a user and his related persons, who are also users)
I want to find out if an address exists for either a user or for his related users in SQL. How to achieve this ?
You can combine two rules and search on the combined table as below
SELECT * FROM
(
SELECT username,id,Address.Address
FROM Person
INNER JOIN Address ON Person.id = Address.Userid
UNION ALL
SELECT username,id,Address.Address
FROM Person
INNER JOIN Relationship ON Relationship.Relatedid = Person.id
INNER JOIN Address ON Relationship.Userid = Address.Userid
) as RES
WHERE Address = 'xyz road'
Also you can find DBFiddle link to workout
Query:
select p.id,p.username,(case when a.userid is null then 'No' else 'Yes'end) IsAddressAvailable
from Person p
left join Address a on p.id=a.Userid
Output:
id
username
IsAddressAvailable
1
Carry
Yes
2
Carry-Father
No
3
Carry-Mother
Yes
db<fiddle here
A user can have many interests.
An interest can be interested to many users.
My database looks like that:
Users table:
id - primary key,
name,
email,
Interests table:
id - primary key,
title
Users_To_Interests table:
id - primary key,
user_id(id from users table)
interest_id(id from interests table)
How can I improve Users_To_Interests table to be able to pick all users who have the same interest efficiently? user_id and interest_id columns don't have indexes or keys. If I need to add them, please show me how can I make that.
Edition 1: For example,
user1 has interests : interest1, interest2, interest3;
user2 has interests : interest3, interest4;
user3 has interests : interest3, interest5;
user4 has interests : interest4;
If I want to get all users who have interest1, I should receive user1;
If I want to get all users who have interest2, I should receive user1;
If I want to get all users who have interest3, I should receive user1, user2, user3;
The query to get users for interest #3 is very simple (use IN or EXISTS). With an index on users_to_interests(interest_id, user_id) this should be very fast.
select *
from users
where id in (select user_id from users_to_interests where interest_id = 3);
Here is a query which would find all users having interests 1 and 2. It should be clear how to generalize this to any number of interets. The subquery aggregates over users and finds those users who have the interests we want. We then join this back to the Users table to get the full information for each user.
SELECT
t1.*
FROM Users t1
INNER JOIN
(
SELECT ui.user_id
FROM Users_To_Interests ui
INNER JOIN Interests i
ON ui.interest_id = i.id
WHERE i.title IN ('interest2', 'interest3')
GROUP BY ui.user_id
HAVING COUNT(DISTINCT i.id) = 2
) t2
ON t1.id = t2.user_id;
I am trying to develop a function which shows me friends of friends, and how many mutual friends I have with those users. So far, I have been able to do the functions separately but not together.
Here is the main view I am using called userfriends. Where user1 is the first user and user2 is the friend.
This is the function I have developed to see mutual friends between two users
SELECT id FROM users
WHERE id IN (
SELECT user2 FROM userfriends WHERE user1 = me
) AND id IN (
SELECT user2 FROM userfriends WHERE user1 = second
)
Users is a main table which can link the user id found in the userfriends table to information about the user. Me and second are variables in the stored procedure which emulate the search for first and second users. This function works to plan.
The second function I have is to see all the users who are friends with my friends, but not with me.
SELECT user2 AS id
FROM userfriends
WHERE user1 IN (
#Selects my friends
SELECT user2 FROM userfriends
WHERE user1 = me
)
AND user2 <> me #Makes sure is not me
AND user2 NOT IN ( #Makes sure not already friend
SELECT user2 FROM userfriends
WHERE user1 = me
)
Again, all working to plan and me represents the user id. This will return a list of all my friends friends.
What I want to be able to get instead of a list of mutual users, or a list of my friends friends is:
A table which has my friends friend user ID and how many mutual friends me and that user shares. Etc: user: 1, friends_in_common: 103. If I'm not clear enough please ask and I will try and make it clearer. The two functions do it by themselves, but I'm just not sure how to merge it together.
-- use a self-join of userfriend*userfriend
-- to find all the friends that moi&toi have in common
-- , and count them.
-- (optionally) suppress the rows for (toi<=moi)
-- , because there are basically the same as the corresponding rows with
-- (toi>moi)
-- -----------------------------------
SELECT DISTINCT
uf1.user1 AS moi
, uf2.user1 AS toi
, COUNT(*) AS cnt
FROM userfriend uf1
JOIN userfriend uf2 ON uf1.user2 = uf2.user2
WHERE uf1.user1 < uf2.user1 -- Tie breaker, symmetry remover
GROUP BY uf1.user1, uf2.user1
;
I need help querying the friendID from a table.
My table stores the user id of two members who are friends together.
But in order to store a "friendhship" b/w two members I would have to store two records like this:
friendshipID | userID | friendID
1 | 5 | 10
2 | 10 | 5
Yet, that seems heavy for the DB when we really only need to store the first record as that is sufficient as it contains both ids of both members.
However, the trouble comes when I want to query the records of the friends of ID=5. Sometimes the ID is in the userID column and other times it is in the friendID column.
This is the query I am using:
SELECT *
FROM friends
WHERE userID = '5'
OR friendID = '5'
But what I want to do is something like this
SELECT
if $userID=5 then userID as myfriend
else friendID=5 then friendID as myfriend
FROM friends WHERE userID='5' OR myfriendID='5'
Hope that makes sense. In the end I would like to have all the friends ID's of member #5 and not bring up results with #5 as the friend or user....but just his friends.
This query would return the Id value, and name, of the friends of #5 as shown in this SQL Fiddle Example
SELECT f.FriendId AS FriendId
, u.Name AS FriendName
FROM FriendTable AS f
INNER JOIN UserAccount AS u ON f.FriendId = u.UserId
WHERE f.UserId = 5
UNION
SELECT f.UserId AS FriendId
, u.Name AS FriendName
FROM FriendTable AS f
INNER JOIN UserAccount AS u ON f.UserId = u.UserId
WHERE f.FriendId = 5
The UNION will remove duplicates, making this query work for both a single record of friends, or the 2 record friendship you mention in the comment. You shouldn't need the 2 record friendship though, because there is no new information being stored in the second record that you cannot get from only having one record.
I have a database table called users with a primary key of user_id for each user.
I also have a table called friends with two fields, user_id and friend_user_id.
The user_id field is always the lowest of the two user_id's in order to avoid duplicate entries.
Say I have two users in mind, (lets say user id 1 and user id 4 although they could be anything).
How would I return all rows from the users table for users that are friends with user 1 and user 4 (i.e mutual friends)?
I will give you the recipe:
Find all friends of user 1
Find all friends of user 2
Intersect them and the result will be the mutual friends.
Much like this:
UPDATE: Here's the query:
select f.friend_user_id from friends f where f.friend_user_id in (
select friend_user_id from friends where user_id=<id_of_user_a>)
and f.user_id=<id_of_user_b>
The ids returned by above query will be the id of all the users that are mutual friends of user_a and user_b. If you want to get all the details (name, etc) about those users, then do this:
select f.friend_user_id,u.* from friends f inner join users u
on u.user_id=f.friend_user_id
where f.friend_user_id in (
select friend_user_id from friends where user_id=<id_of_user_a>)
and f.user_id=<id_of_user_b>
SELECT friends.friend_user_id FROM user, friends
INNER JOIN friends ON friends.user_id = user.user_id
WHERE user.user_id = 1
AND friend.friend_user_id
IN (SELECT friends.friend_user_id
FROM user, friends
INNER JOIN friends ON friends.user_id = user.user_id
WHERE user_id = 4)