I have a users table and user_followings table. The tables have the basic structure:
users: id, name, email
users_followings: following_user_id, follower_user_id
follower_user_id is someone who is following some other person.
following_user_id is someone who is being followed by some other
person
I want that one can click on a particular user to see all the information like who are following him/her and who are the people that he/she is follwing.
SELECT
users.id,
users.name,
users.email
from users
JOIN user_followings ON
user_followings.follower_user_id = users.id
WHERE user_followings.following_user_id = 1
This query basically joins two table and fetches desired result.
Now suppose a user named 'A' is logged in and he is looking at user X's profile. There are many people who have followed user X.
Let's say John, Mike, Rusev, Jack etc
How can write a query that tells whether logged in User 'A' is following John, Mike, Rusev, Jack etc or not along with the query that is above there.
So user A should be able to know whether he is following John, Mike, Rusev, Jack etc or not
My understanding is that OP wants to see what users are following the current user (A) that also follows the user A is viewing (X)
In my example A is id = 1 and X is id = 6
SELECT fu.id, fu.name, fu.email
FROM users u
JOIN users_followings f ON f.userId = u.id
JOIN users fu on fu.id = f.follower
WHERE f.userId = 1
AND f.follower IN (SELECT follower
FROM users_followings
WHERE userId = 6)
I changed follower_user_id to follower and following_user_id to userId to not confuse myself
Supposed the user with id=1 is viewing the details of the user with id=2 and you want to the user with id=1 to know if the followings or followers of user with id=2 are related with user with id=1 in any way. Try this:
SELECT C.*,
(SELECT 1 FROM user_followings D WHERE D.following_user_id=1 AND
C.id=D.follower_user_id LIMIT 1) flwx_viewing_user,
(SELECT 1 FROM user_followings E WHERE E.follower_user_id=1 AND
C.id=E.following_user_id LIMIT 1) viewing_user_flwx
FROM
(SELECT A.id, A.name, A.email, 'following' relation
FROM users
WHERE EXIST (SELECT 1
FROM user_followings B
WHERE B.following_user_id=2)
UNION ALL
SELECT A.id, A.name, A.email, 'followers' relation
FROM users
WHERE EXIST (SELECT 1
FROM user_followings B
WHERE B.follower_user_id=2)) C;
I'm not sure I get it right but given ID=1 for A and ID=5 for X.
This query returns for every user that follows X the info if it is followed by A
SELECT
*,
CASE WHEN exists(
SELECT *
FROM following AFOLLOW
WHERE AFOLLOW.follower_user_id = 1
AND XFOLLOWED.follower_user_id = AFOLLOW.following_user_id)
THEN 'FOLLOWING'
ELSE 'NOTFOLLOWING' END
FROM following XFOLLOWED
WHERE following_user_id = 5
AND follower_user_id <> 1;
Related
I have simple table friends that look like that:
With the id of a person (id_friend) and the id of its friend (id_friend_of).
I'm trying to get all the IDs of friends of a specific user with a depth, so get all people linked to a specific user with a determined depth.
What I'm trying for a depth of 2 (get the friends of the user and the friends of its friends) :
SELECT DISTINCT
a.id_friend_of
FROM friend a
JOIN friend b
ON b.id_friend = a.id_friend_of
WHERE a.id_friend = 1 AND
b.id_friend <> a.id_friend
But it's not working, I'm only getting the friends of the user but not the friends of friends.
What can I do to make this work?
get the friends of the user and the friends of its friends
You can get the friends of the user with a simple filtered query on the table and the friends of friends with a self join of the table.
Then use UNION to get the results of the 2 queries, which will also remove duplicates:
SELECT id_friend_of
FROM friend
WHERE id_friend = 1
UNION
SELECT f2.id_friend_of
FROM friend f1 INNER JOIN friend f2
ON f2.id_friend = f1.id_friend_of
WHERE f1.id_friend = 1 AND f2.id_friend_of <> 1
For levels above 2, it's better to use a recursive query (for MySql 8.0+):
WITH RECURSIVE cte AS (
SELECT *, 1 level
FROM friend
WHERE id_friend = 1
UNION ALL
SELECT f.*, level + 1
FROM cte c INNER JOIN friend f
ON f.id_friend = c.id_friend_of
WHERE f.id_friend_of <> 1 AND level < 2 -- for level = 2
)
SELECT DISTINCT id_friend_of
FROM cte
See a simplified demo.
I've the following schema:
Users
-----
id
name
Conversations
-------------
id
other
Partecipants (join table)
------------
id
user_id
conversation_id
other
An user can have many conversations and a conversation belongs to many users.
I need to select all the conversations of an user with a subset of other users.
My try is (do not work):
SELECT *
FROM `conversations`
INNER JOIN `participants` ON `conversations`.`id` = `participants`.`conversation_id`
WHERE `participants`.`user_id` = 1
AND (participants.user_id IN (4,6))
GROUP BY participants.conversation_id
Any idea?
Hmmm. Here is a method using group by and having:
select p.conversation_id
from participants p
group by p.conversation_id
having sum(p.user_id = 1) > 0 and -- user 1 in conversation
sum(p.user_id in (4, 6)) > 0; -- user 4 and/or 6 in conversation
What I understand from your questions was you want to see users "4,6" involved in conversation with user_id = 1. to do so try following query.
select * from (SELECT conversations.id as conversation_id, participants.user_id as selectedUser, GROUP_CONCAT(participants.user_id) AS participants
FROM `conversations`
INNER JOIN `participants` ON `conversations`.`id` = `participants`.`conversation_id`
GROUP BY participants.conversation_id ) as derivedTable
where
selectedUser=1 and
(participants like '%4%' and participants like '%6%')
what above query does is. initially it will take all record from conversation and participants table and concat all participants agains user_id=1. then outer query checks are pretty clear to find user_id and participants have 4 and 6.
I have two tables. One contains User and company relationship a show below
User_company
UserId CompanyId
1 2
2 1
3 1
4 2
Another table holds user information
User
Id Name City
1 Peter LA
2 Harry SF
3 John NY
4 Joe CI
How do I make a statement which will give me All the users which are in company 1? Will something like
Select * from User where Id in (Select UserId from User_company where CompanyId = 1)
work?
SELECT * from User
left join User_company on User_company.UserId=User.Id
This would work...
SELECT * works but can be sluggish over time as it may not scale well with more data.
FROM User
WHERE Id in (Select UserId from User_company where CompanyId = 1)
So would this.. - best if you need data from both tables.
SELECT *
FROM User U
INNER JOIN User_Company UC
ON U.ID = UC.UserID
WHERE UC.CompanyID = 1
As would this - Probably the fastest if you just need data from user table.
Select * from User U
where exists (Select * from User_Company UC where U.ID = UC.UserID and CompanyID = 1)
OUTER joins are only needed if you need all records from one table and only those that match in another.
As to which is the best above: it depends on existing indexes and other requirements. Any of the above will return what's been asked for.
Try this
Select u.*
from User u
inner join User_company uc
on u.Id = uc.UserId
and uc.CompanyId = 1
BTW, what's wrong with the query you have posted? It will work as well fine. Just that it's a subquery and you better replace it with Join for performance.
Select * from User where Id in
(Select UserId from User_company where CompanyId = 1)
SELECT U.* FROM User AS U LEFT JOIN
User_company AS UC ON U.Id = UC.UserId WHERE UC.CompanyId = 1
want mysql query for finding mutual friend between two friend but
I am maintain the friendship of user in one way relationship for ex.
first is users table
id name
1 abc
2 xyz
3 pqr
Now second table is friend
id user_id friend_id
1 1 2
2 1 3
3 2 3
Now here i can say that abc(id=1) is friend of xyz(id=2) now similar way the xyz is friend of abc but now i want to find mutual friend between abc(id=1) and xyz(id=2) that is pqr so I want mysql query for that.
REVISED
This query will consider the "one way" relationship of a row in the friend table to be a "two way" relationship. That is, it will consider a friend relationship: ('abc','xyz') to be equivalent to the inverse relationship: ('xyz','abc'). (NOTE: we don't have any guarantee that both rows won't appear in the table, so we need to be careful about that. The UNION operator conveniently eliminates duplicates for us.)
This query should satisfy the specification:
SELECT mf.id
, mf.name
FROM (
SELECT fr.user_id AS user_id
, fr.friend_id AS friend_id
FROM friend fr
JOIN users fru
ON fru.id = fr.user_id
WHERE fru.name IN ('abc','xyz')
UNION
SELECT fl.friend_id AS user_id
, fl.user_id AS friend_id
FROM friend fl
JOIN users flf
ON flf.id = fl.friend_id
WHERE flf.user IN ('abc','xyz')
) f
JOIN users mf
ON mf.id = f.friend_id
GROUP BY mf.id, mf.name
HAVING COUNT(1) = 2
ORDER BY mf.id, mf.name
SQL Fiddle here http://sqlfiddle.com/#!2/b23a5/2
A more detailed explanation of how we arrive at this is given below. The original queries below assumed that a row in the friend table represented a "one way" relationship, in that "'abc' ff 'xyz'" did not imply "'xyz' ff 'abc'". But additional comments from the OP hinted that this was not the case.
If there is a unique constraint on friend(user_id,friend_id), then one way to get the result would be to get all of the friends of each user, and get a count of rows for that friend. If the count is 2, then we know a particular friend_id appears for both user 'abc' and for 'xyz'
SELECT mf.id
, mf.name
FROM friend f
JOIN users uu
ON uu.id = f.user_id
JOIN users mf
ON mf.id = f.friend_id
WHERE uu.name IN ('abc','xyz')
GROUP BY mf.id, mf.name
HAVING COUNT(1) = 2
ORDER BY mf.id, mf.name
(This approach can also be extended to find a mutual friend of three or more users, by including more users in the IN list, and changing the value we compare the COUNT(1) to.
This isn't the only query that will return the specified resultset; there are other ways to get it as well.
Another way to get an equivalent result:
SELECT u.id
, u.name
FROM ( SELECT f1.friend_id
FROM friend f1
JOIN users u1
ON u1.id = f1.user_id
WHERE u1.name = 'abc'
) t1
JOIN ( SELECT f2.friend_id
FROM friend f2
JOIN users u2
ON u2.id = f2.user_id
WHERE u2.name = 'xyz'
) t2
ON t2.friend_id = t1.friend_id
JOIN users u
ON u.id = t1.friend_id
ORDER BY u.id, u.name
NOTES
These queries do not check whether user 'abc' is a friend of 'xyz' (the two user names specified in the WHERE clause). It is only finding the common friend of both 'abc' and 'xyz'.
FOLLOWUP
The queries above satisfy the specified requirements, and all the examples and test cases provided in the question.
Now it sounds as if you want a row in that relationship table to be considered a "two way" relationship rather than just a "one way" relationship. It sounds like you want to want to consider the friend relationship ('abc','xyz') equivalent to ('xyz','abc').
To get that, then all that needs to be done is to have the query create the inverse rows,, and that makes it easier to query. We just need to be careful that if both those rows ('abc','xyz') and ('xyz','abc') already exist, that we don't create duplicates of them when we invert them.
To create the inverse rows, we can use a query like this. (It's simpler to look at this when we don't have the JOIN to the users table, and we use just the id value:
SELECT fr.user_id
, fr.friend_id
FROM friend fr
WHERE fr.user_id IN (1,2)
UNION
SELECT fl.friend_id AS user_id
, fl.user_id AS friend_id
FROM friend fl
WHERE fl.friend_id IN (1,2)
It's simpler if we don't include the predicates on the user_id and friend_id table, but that could be a very large (and expensive) rowset to materialize.
try this:
given that you want to get the mutual friends of friends 1 & 2
select friend_id into #tbl1 from users where user_id = 1
select friend_id into #tbl2 from users where friend_id = 2
select id, name from users where id in(select friend_id from #tbl1 f1, #tbl2 f2 where f1.friend_id=f2.friend_id)
I am having a hard time understanding joins on mySQL, and I cannot find any similar example to work with.
Suppose I have two tables: users and users_info.
in users I have id, email and password fields while, in users_info I have all their information, like name, surname, street, etc.
so, if I am getting a user like this:
SELECT * FROM users WHERE id = 43
and their information like this:
SELECT * FROM users_info WHERE id = 43
I will basically get 2 results, and 2 tables.
I understand now that I need to use join so that they are all together, but I just can't figure out out.
Any help?
It seems like both tables users and user_info are related with each others by the column id therefore you need to join them using this column like this:
SELECT
u.id,
u.email,
u.password,
i.name,
i.surname,
i.street
FROM users AS u
INNER JOIN user_info AS i ON u.id = i.id;
This will only select the fields id, email, ... etc. However, if you want to select all the columns from both the tables use SELECT *:
SELECT *
FROM users AS u
INNER JOIN user_info AS i ON u.id = i.id;
If you want to input the id and get all of these data for a specific user, add a WHERE clause at the end of the query:
SELECT *
FROM users AS u
INNER JOIN user_info AS i ON u.id = i.id
WHERE u.id = 43;
For more information about JOIN kindly see the following:
Join (SQL)From Wikipedia.
Visual Representation of SQL Joins.
Another Visual Explanation of SQL Joins.
Here's an example
SELECT * FROM users u
INNER JOIN users_info i
ON u.id=i.id
this means, you are joining users table and users_info table
for example
users
id name
---- -------
1 abc
2 xyz
users_info
id email
--- ------
1 abc#aaa.com
2 xyz#aaa.com
the query will return
id name email
--- ----- -------
1 abc abc#aaa.com
2 xyz xyz#aaa.com
Here's a nice tutorial
You can also do:
SELECT users.*, users_info.*
FROM users, users_info
WHERE users.id = users_info.id AND users.id = 43;
This means:
"Get me all the columns from the users table, all the columns from the users_info table for the lines where the id column of users and the id column of users_info correspond to each other"