Get 2x same table's column 1 result - mysql

I have a users table and a friends table.
I want to get the friendships of 1 user, but getting both user info in results.
For example, let's say I have these tables:
- users (_id_, username, firstname, lastname)
- friends (_#id1, #id2_)
Here are some data:
- users (1, foo, Foo, BAR)
(2, john, John, DOE)
- friends (1, 2)
If I query fiendship WHERE id1 = 1 OR id2 = 1, I know that with a JOIN I can get for each row, the user data. But how to get in 1 result (1 row) both users data?

SELECT
u1.*,
u2.*
FROM
friends
JOIN users AS u1
ON friends._#id1=u1._id_
JOIN users AS u2
ON friends.#id2_=u2._id_

SELECT u1.*, u2.*
FROM users u1
JOIN friends f1
ON u1._ID_ = friends._#id1_
JOIN users u2
ON u2._ID_ = friends._#id2_
Each row will contain all the info from one user, and then all the info from the second user. You might want to replace that first JOIN friends f1 with LEFT OUTER JOIN friends f1 to also display a row for users without friends.
Careful: a user with multiple friends will show multiple rows. There is no automatic way in MySQL to pivot these rows to columns. You can however GROUP on the u1._ID_, and then use the GROUP_CONCAT function to display the friends information.

Related

SQL INNER JOIN only returns the first result

I have a Many to Many relationship between Pets and Users, with a UserPets join table. I've been trying to write an SQL query that would return the user name with the amount of times walked. However, I've only been able to return a user and a timesWalked and they are not even the associated ones.
The current SQL statement I have is:
SELECT user_pets.timesWalked, users.name
FROM user_pets
INNER JOIN users ON user_pets.user_id = users.id
And the returned result is:
[{"timesWalked"=>20, "name"=>"user1", 0=>20, 1=>"user1"}]
In this instance, user1 is not the one that walked the dog 20 times, which is the association I need.
table name: users
name
user1
user2
user3
table name: user_pets
name timesWalked userId petId
usep1 10 2 1
usep2 20 1 3
usep3 5 1 2
table name: pets
name
pet1
pet2
pet3
My expected result is:
[{"timesWalked"=>20, "name"=>"user1"}]
[{"timesWalked"=>10, "name"=>"user3"}]
[{"timesWalked"=>5, "name"=>"user2"}]
In this instance, the user name from the User's table is being associated with timesWalked from the user_pets table
How can I return all the timesWalked with all the user names who walked the pet?
You can use inner join to achieve this.
Below query lists all the users who have walked all the pets for total number of time.
i.e. User 1 has walked two pets for 2 times each.
select
up.timesWalked, u.name as UserName, p.name as PetName
from user_pets up
inner join users u on up.user_id = u.id
inner join pets p on up.pet_id = p.id
Have a look at this fiddle : http://sqlfiddle.com/#!17/c91a1/2

How to make many to many relationship table efficient for SELECT queries in MySQL?

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;

Join two tables on a specific table fields

I have two tables activity_log and user_followers. I have to join these two tables and get the activity of a user with the user activity that he is following (let's say user_id 6 is following user_id 4). But the below query only returning the activity of the user having the id of 6. I want to get the activity of the user with the id of 6 plus the activity of the user he is following.
Query
SELECT activity_log.*
FROM activity_log
join user_followers ON activity_log.user_id = user_followers.follow_id
AND activity_log.user_id = 6;
activity_log:
user_followers:
Sounds like you want user_id 6's activity plus activity of users he's following. That would be:
SELECT activity_log.*
FROM activity_log
LEFT OUTER JOIN user_followers
ON activity_log.user_id = user_followers.follow_id
WHERE (activity_log.user_id = 6 OR ISNULL(user_followers.user_id,0) = 6);
The LEFT OUTER is used in case user_id 6 has no followers.

basic join on mysql

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"

mysql query help to find mutual friends on social networking site

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)