Join between two tables on multiple column - mysql

I am wondering if I can have join between two tables but on different columns? Let me explain because it is different with most of the cases that I've seen...
I have a table for all the messages between users and each user has a unique user id. so In the first table I have:
Tx User Id .......... Rx. User Id .......... Date ............ Message
and in user tables I have
user Id .............. User name
Can I have a join query that gives me
Tx User "Name" ........... Rx. User "Name: ....... Date ....... Message
The problem is that in my join apparently I can only define
SELECT messages.* users.name
FROM messages JOIN
users
ON messages.RxId = users.id OR messages.TxId = users.id
which is only 1 field, but as I explained above I need 2 field as Rx user name and Tx. User Name based on which id in my messages table is matched.
Thanks a lot in advanced.

You want two joins. And for this you need to learn about table aliases (a good thing):
SELECT m.*, urx.name, utx.name
FROM messages m LEFT JOIN
users urx
ON m.RxId = urs.id LEFT JOIN
users utx
ON m.TxId = utx.id;

Related

How to find out results for not matching particular condition in SQL from multiple tables?

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

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 : Finding related attributes

I am a bit new to MySQL and trying my hands on learning it. However I got stuck with an query that goes as follows:
I have 2 tables: Table 1 contains details of lists created by a user. The fields are listid, listname, creatorid, createdat,membercount;
Table 2 stores data of members of each list: The fields are listid, userid;
The query I need to process is as follows: Find out all the pairs of users of the form (u1,u2) where both of the following conditions are satisfied
i. u1 has created at least one list and u2 is a member of that list.
ii. u2 has created at least one list and u1 is a member of that list.
Note: listid in the table 2 is the foreign key for listid in table 1.
How about this?
SELECT l.creatorid AS u1, u.userid AS u2
FROM table2 AS u
INNER JOIN table1 AS l ON l.listid = u.listid
Returns every user from Table2 and the ID of the creator of the corresponding list.